微信小程序 仿微信聊天界面
1. 需求效果图
2. 方案
为实现这样的效果,首先要解决两个问题:
2.1.点击输入框弹出软键盘后,将已有的少许聊天内容弹出,导致看不到的问题
点击输入框弹出软键盘后,将已有的少许聊天内容弹出,导致看不到的问题。
(1)首先我们需要将input的自动向上推给关掉,这里有个坑:
在input组件中添加:adjust-position=‘{{false}}’,而不是:adjust-position=‘false’。
这么做虽然不再向上推,但却导致了软键盘弹起时,会遮挡屏幕下部分的消息。
(2)如何解决软键盘弹起时,会遮挡屏幕下部分的消息?
当软键盘弹起时,将scroll-view的高度缩短至软键盘遮挡不到的屏幕上方部分,当软键盘收起时,再将scroll-view的高度还原,这样解决了遮挡问题。
提示:
input中的bindfocus='focus’可获取软键盘高度并监听软键盘弹起,bindblur='blur’可监听软键盘收起,var windowHeight = wx.getSystemInfoSync().windowHeight;可获得屏幕高度。
scrollHeight(滚动条高度) = windowHeight(屏幕高度) - 软键盘高度;
最后将input组件放在软键盘上面就完成了。
2.2.键盘弹出或收起时,聊天消息没有自动滚到最底部
首先解决第二个问题,自动滚动到最底部,这很简单,这里提供三种方法(推荐第三种):
(1)计算每条消息的最大高度,设置scroll-top=(单条msg最大高度 * msg条数)px。
(2)用 将展示msg的目标scroll-view包裹,
通过js获取到该view的实际高度:
var that = this;
var query = wx.createSelectorQuery();
query.select('.scrollMsg').boundingClientRect(function(rect) {that.setData({scrollTop: rect.height+'px';});
}).exec();
(3)(推荐)将所有msg都编号如:msg-0,msg-1,msg-2… 直接锁定最后一条msg,滚动到那里。
在scroll-view中添加:scroll-into-view=‘{{toView}}’,
在wx:for后面添加:wx:for-index=“index”,
在每个msg布局中添加:id=‘msg-{{index}}’,
this.setData({toView: 'msg-' + (msgList.length - 1)
})
3. 代码
3.1.gridGroup.wxml
<view class="page-layout"><view class="page-body" id="x_chat"><view wx:key="{{index}}" wx:for="{{chatList}}"><view class="chat-item-body"><view class="chat-item-time">{{item.time}}</view><view wx:key="{{index}}" wx:if="{{item.type == '0'}}" class="chat-item-layout chat-left"><view class="chat-inner-layout"><view class="chat-item-name">{{item.name}}</view><view class="chat-item-msg-layout"><image class="chat-item-photo" bindtap="scanClick" src="{{item.photoUrl}}" mode="aspectFit"></image><view class="chat-inner-msg-left">{{item.msg}}</view></view></view></view></view><view wx:key="{{index}}" wx:if="{{item.type == '1'}}" class="chat-item-layout chat-right"><view class="chat-inner-layout"><view class="chat-item-name-right">{{item.name}}</view><view class="chat-item-msg-layout"><view class="chat-inner-msg-right">{{item.msg}} </view><image class="chat-item-photo" bindtap="scanClick" src="{{item.photoUrl}}" mode="aspectFit"></image></view></view></view></view></view><view class="submit-layout"><input class="submit-input" placeholder="点击输入,开始聊天吧" value="{{inputTemp}}" bindinput="bindKeyInput" /><view class="submit-submit" type="submit" size="mini" bindtap="submitTo">发送</view></view>
</view>
3.2.gridGroup.wxss
.page-layout {width: 100%;height: 100%;box-sizing: border-box;
}.page-body {width: 100%;display: flex;flex-direction: column;padding-bottom: 56px;
}.chat-item-body {display: flex;flex-direction: column;margin-top: 20rpx;
}.chat-item-time {width: 100vw;text-align: center;font-size: 28rpx;color: #ccc;border-radius: 10rpx;margin-top: 40rpx;
}.chat-item-layout {display: block;max-width: 82%;margin: 1rpx 5rpx;box-sizing: border-box;padding: 0 1rpx;
}.chat-right {float: right;
}.chat-left {float: left;
}.chat-inner-layout {display: flex;flex-direction: column;
}.chat-item-photo {width: 70rpx;height: 70rpx;min-width: 70rpx;min-height: 70rpx;border-radius: 50%;
}.chat-item-msg-layout {display: flex;flex-direction: row;
}.chat-item-name {display: flex;flex-direction: row;align-items: center;font-size: 28rpx;color: #999;border-radius: 10rpx;margin: 5rpx 0 0 80rpx;
}.chat-item-name-right {display: flex;flex-direction: row;align-items: center;font-size: 28rpx;color: #999;border-radius: 10rpx;margin: 5rpx 0 0 5rpx;
}.chat-inner-msg-left {display: inline-block;flex-direction: row;align-items: center;color: #000;font-size: 30rpx;border-radius: 10rpx;background: white;padding: 15rpx 5rpx 15rpx 15rpx;margin-left: 12rpx;
}.chat-inner-msg-right {display: inline-block;color: #000;font-size: 30rpx;border-radius: 10rpx;background: #87EE5F;padding: 15rpx 5rpx 15rpx 15rpx;margin-right: 12rpx;
}.submit-layout {position: absolute;bottom: 0;width: 100%;background: #eee;flex-direction: row;
}.submit-layout {width: 100%;position: fixed;bottom: 0;border-top: 1px solid #ddd;padding: 10rpx 0;display: flex;flex-direction: row;align-items: center;
}.submit-input {flex: 1;background: #fff;margin: 5rpx 10rpx;border-radius: 5rpx;padding: 15rpx 20rpx;color: #333;font-size: 30rpx;
}.submit-submit {background-color: #13c25f;color: #333;font-weight: 700;font-size: 30rpx;border-radius: 10rpx;padding: 18rpx 30rpx;margin-right: 10rpx;
}
3.3.gridGroup.js
import tinyCommunityJson from '../../public/json/tinyCommunityJson';
Page({data: {inputValue: '',chatList: tinyCommunityJson.data.rows,},onLoad: function (options) {var title = options.title// 设置标题wx.setNavigationBarTitle({title: title,})//滚动到页面底部that.pageScrollToBottom()},/*** 输入监听*/bindKeyInput: function (e) {this.setData({inputValue: e.detail.value})},/*** 发送*/submitTo: function (e) {var that = this;var inputValue = that.data.inputValueif (!inputValue) {wx.showToast({title: '请输入聊天内容',icon: 'none'})return}this.setData({inputTemp: ""})var chatObj = {}chatObj.type = '1'chatObj.name = ''chatObj.msg = inputValuechatObj.time = that.getCurTime()chatObj.photoUrl = 'https://zhsq/icon_chat_photo_three.jpg'var chatList = that.data.chatListchatList.push(chatObj);that.setData({chatList: chatList})//滚动到页面底部that.pageScrollToBottom()},/*** 获取当前时间*/getCurTime() {var date = new Date()var y = date.getFullYear();var m = date.getMonth() + 1;m = m < 10 ? ('0' + m) : m;var d = date.getDate();d = d < 10 ? ('0' + d) : d;var h = date.getHours();h = h < 10 ? ('0' + h) : h;var minute = date.getMinutes();minute = minute < 10 ? ('0' + minute) : minute;var second = date.getSeconds();second = second < 10 ? ('0' + second) : second;return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;},/*** 滚动到页面底部*/pageScrollToBottom: function () {let that = this;wx.createSelectorQuery().select('#x_chat').boundingClientRect(function (rect) {let top = rect.height * that.data.chatList.length;wx.pageScrollTo({scrollTop: top,duration: 100})}).exec()},
})
3.4.tinyCommunityJson.js
const data = {rows: [{type: '0',name: '群主',msg: '大家好,欢迎进入微社区群,如有问题可在群里聊天询问',time: '2024-01-26 13:43:12',photoUrl: 'https://zhsq/icon_chat_photo_two.jpg',},{type: '0',name: '小助手',msg: '2024微报事、微呼应活动正在进行中,希望大家踊跃参加。',time: '2024-01-26 13:43:15',photoUrl: 'https://zhsq/icon_service.png',},{type: '1',name: '',msg: '已参加微呼应活动',time: '2024-01-26 13:56:10',photoUrl: 'https://zhsq/icon_chat_photo_three.jpg',},{type: '0',name: '第五网格员',msg: '已参加微报事活动',time: '2024-01-26 13:59:12',photoUrl: 'https://zhsq/icon_chat_photo_one.jpg',},
],
};
module.exports = {data: data,
}
4. 优化
聊天框三角形的制作和使用
4.1. gridChat.wxml
<view><!-- 右侧布局 --><view class="right-layout"><view class='right-msg'>我是右侧布局我是右侧布局我是右侧布局我是右侧布局我是右侧布局</view><view class="right-arrow-layout"><image class="right-arrow-img" src='https://zhsq/icon_arrow_right_green.png' mode='widthFix'></image></view><image class="right-arrow-photo" src='https://zhsq/icon_chat_photo_one.jpg' mode='aspectFill'></image></view><!-- 左侧布局 --><view class="left-layout"><image class="left-arrow-photo" src='https://zhsq/icon_chat_photo_two.jpg' mode='aspectFill'></image><view class="left-arrow-layout"><image class="left-arrow-img" src='https://zhsq/icon_arrow_left_white.png' mode='widthFix'></image></view><view class='left-msg'>我是左侧布局</view></view>
</view>
4.2. gridChat.wxss
page {background-color: #eee;
}
/* 左侧布局 */
.left-layout {display: flex;justify-content: flex-start;padding: 20rpx 60rpx 2vw 2vw;
}.left-arrow-photo {width: 60rpx;height: 60rpx;min-width: 60rpx;min-height:60rpx ;border-radius: 50%;margin-top: 5rpx;
}.left-msg {font-size: 32rpx;color: #444;line-height: 45rpx;padding: 10rpx 20rpx 10rpx 5rpx;background-color: white;margin-left: -12rpx;border-radius: 10rpx;z-index: 10;
}.left-arrow-layout {width: 35rpx;height: 65rpx;display: flex;align-items: center;z-index: 9;
}.left-arrow-img {width: 35rpx;
}/* 右侧布局 */
.right-layout {display: flex;justify-content: flex-end;padding: 20rpx 2vw 2vw 15vw;
}
.right-arrow-photo {width: 60rpx;height: 60rpx;min-width: 60rpx;min-height:60rpx ;border-radius: 50%;margin-top: 5rpx;
}
.right-msg {font-size: 32rpx;color: #444;line-height: 45rpx;padding: 10rpx 5rpx 10rpx 20rpx;background-color: #96EB6A;margin-right: -12rpx;border-radius: 10rpx;z-index: 10;
}.right-arrow-layout {width: 35rpx;height: 65rpx;margin-right: 5rpx;display: flex;align-items: center;z-index: 9;
}.right-arrow-img {width: 35rpx;
}
相关文章:

微信小程序 仿微信聊天界面
1. 需求效果图 2. 方案 为实现这样的效果,首先要解决两个问题: 2.1.点击输入框弹出软键盘后,将已有的少许聊天内容弹出,导致看不到的问题 点击输入框弹出软键盘后,将已有的少许聊天内容弹出,导致看不到的问…...
中国社会科学院大学-新加坡社科大学 招生简章
Singapore University of Social Sciences--University of Chinese Academy of Social Sciences Doctor of Business Administration (DBA) Programme in Global Strategy and Leadership 一、项目简介 全球经济正在经历由科技进步和创新、政治和人口剧烈变化所带来的巨大的不…...

js中继承的详解(一文读懂)
文章目录 一、是什么二、实现方式原型链继承构造函数继承组合继承原型式继承寄生式继承寄生组合式继承 三、总结参考文献 一、是什么 继承(inheritance)是面向对象软件技术当中的一个概念。 如果一个类别B“继承自”另一个类别A,就把这个B称…...
Android studio使用svg矢量图
https://www.iconfont.cn/ https://www.jyshare.com/more/svgeditor/ https://editor.method.ac/ https://inloop.github.io/svg2android/ Pattern Monster - SVG 图案生成器 Android studio使用svg矢量图自适应不同的分辨率, svg矢量图绘制以及转换为And…...
《Access Path Selectionin a Relational Database Management System》论文笔记
以下是根据论文归纳出的一些查询优化器公式和知识点,有没有用不知道,先码起来。 SQL执行优化过程 处理SQL语句是从解析用户输入的SQL语句开始,经过一系列优化过程,最终生成机器代码并执行的过程。这个过程涉及到多个复杂的步骤&…...

【AI_Design】Midjourney学习笔记
目录 后缀解析Promot合格使用prompt关键词描述 关键词化合作用关键词网站推荐 联合Chatgpt使用总结 后缀解析 –ar:宽高比设置–c:多样性设置(数值0-100,默认值0)–s:风格化设置(数值0-1000&am…...

面试宝典之深谈JVM
面试宝典之深谈JVM 1.为什么需要JVM,不要JVM可以吗? 1.JVM可以帮助我们屏蔽底层的操作系统 一次编译,到处运行 2.JVM可以运行Class文件 2.JDK,JRE以及JVM的关系 3.我们的编译器到底干了什么事? 仅仅是将我们的 .ja…...

idea配置tomcat
推荐链接:IntelliJ IDEA中配置Tomcat(超详细)_idea怎么配置tomcat服务器-CSDN博客 1,官员下载链接:Apache Tomcat - Welcome! 附本人下载的 tomcat9 的百度网盘链接 链接:https://pan.baidu.com/s/1DpyBGnG4mUGTm5Z…...

【MyBatis】操作数据库——入门
文章目录 为什么要学习MyBatis什么是MyBatisMyBatis 入门创建带有MyBatis框架的SpringBoot项目数据准备在配置文件中配置数据库相关信息实现持久层代码单元测试 为什么要学习MyBatis 前面我们肯定多多少少学过 sql 语言,sql 语言是一种操作数据库的一类语言&#x…...

免费分享一套SpringBoot+Vue药店(药房)管理系统,帅呆了~~
大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue药店(药房)管理系统 ,分享下哈。 项目视频演示 【免费】SpringBootVue药店(药房)管理系统 Java毕业设计_哔哩哔哩_bilibili【免费】SpringBootVue药店(药房)管理系统 Java毕业设计…...

视频怎么加水印?分享两个简单的加水印的方法
在数字媒体时代,视频已经成为信息传播的重要方式。许多人在创作视频是会加上自己独特的水印,防止视频被盗用。水印作为数字版权保护技术的一种,可以有效地防止视频被非法复制、传播或篡改,从而保护创作者的权益和利益。下面我分享…...

Apache Commons Collection3.2.1反序列化分析(CC1)
Commons Collections简介 Commons Collections是Apache软件基金会的一个开源项目,它提供了一组可复用的数据结构和算法的实现,旨在扩展和增强Java集合框架,以便更好地满足不同类型应用的需求。该项目包含了多种不同类型的集合类、迭代器、队…...
MySQL入门篇(10)-聚合函数的应用
MySQL数据库聚合函数的应用 在MySQL数据库中,聚合函数用于计算一组数据的统计值并返回结果。这些函数可以应用于查询语句中,对数据进行汇总、计数、平均值计算等操作。本文将介绍一些常用的MySQL聚合函数及其应用。 1. COUNT函数 COUNT函数用于计算指…...
Vue3基本概念
script部分 export default对象的属性: name:组件的名称 components:存储中用到的所有组件 props:存储父组件传递给子组件的数据 watch():当某个数据发生变化时触发 computed:动态计算某个数据 setup(pro…...
每日OJ题_算法_模拟①_力扣1576. 替换所有的问号
目录 模拟算法原理 力扣1576. 替换所有的问号 解析代码 模拟算法原理 模拟算法是一种常用的计算机算法,它模拟了实际问题的运行过程,并通过数学模型来预测结果。模拟算法可以应用于各个领域,例如物理、化学、生物、计算机网络等等。 模拟算…...

杂题——试题 算法训练 区间最大和
分析: 如果使用两个for循环遍历所有情况,运行会超时解决运行超时的关键点在于:及时停止累加,丢弃当前的子序列 比如【1,-2,3,10】从第一个数字开始的子序列的和小于从第三个数字开始的子序列的和…...
(安卓)跳转应用市场APP详情页的方式
前言 最近在做一个需求,需要从自己APP进入到系统的应用市场 方便用户在应用市场给自己的APP打分 于是查阅了一些资料,下面说一下实现方法 实现方案 一般来说,最简单的方案就是这样: val uri Uri.parse("market://details…...

亚信安全助力宁夏首个人工智能数据中心建成 铺设绿色算力安全底座
近日,由宁夏西云算力科技有限公司倾力打造,亚信安全科技股份有限公司(股票代码:688225)全力支撑,总投资达数十亿元人民币的宁夏智算中心项目,其一期工程——宁夏首个采用全自然风冷技术的30KW机…...
ASP.NET Core WebAPI_解决跨域问题(前端后端)
说明 我的前端框架为Vue3 前后端跨域选其一即可 前端跨域 在项目的根目录找到vite.config.js文件,添加代码: server: {proxy: {/api: {target: https://localhost:xxxx,changeOrigin: true,secure: false},},} axios代码片段: …...

保姆级的指针详解(超详细)
目录 一.内存和地址 1.初识指针 2.如何理解编址 二. 指针变量 三.指针的解引用操作符 1.指针变量的大小 四.指针变量类型的意义 五.指针的运算 1.指针加减整数 2.指针减指针 3.野指针 3.1指针未初始化 3.2指针越界访问 3.3指针指向的空间被提前释放 3.4如何规…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...