Kotlin高仿微信-第9篇-单聊-文本

news2024/11/24 10:54:18

 Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。

Kotlin高仿微信-项目实践58篇,点击查看详情

效果图:

详细的聊天功能请查看Kotlin高仿微信-第8篇-单聊,这里是提示文本功能的部分实现。

实现代码:

我的布局

<RelativeLayout
    android:id="@+id/chat_item_me_content_layout"
    app:layout_constraintEnd_toStartOf="@+id/chat_item_me_avatar"
    app:layout_constraintTop_toTopOf="@+id/chat_item_me_avatar"
    android:layout_width="280dp"
    android:gravity="right"
    android:visibility="gone"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/chat_item_me_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="10dp"
        android:background="@drawable/wc_chat_me3_normal"
        android:gravity="left|center"
        android:paddingVertical="12dp"
        android:paddingLeft="12dp"
        android:paddingRight="18dp"
        android:text="我的"
        android:textColor="@color/black"
        android:textSize="18sp"/>
</RelativeLayout>

好友的布局:

<RelativeLayout
    android:id="@+id/chat_item_other_content_layout"
    app:layout_constraintStart_toEndOf="@+id/chat_item_other_avatar"
    app:layout_constraintTop_toTopOf="@+id/chat_item_other_avatar"
    android:visibility="gone"
    android:layout_width="280dp"
    android:layout_height="wrap_content">
    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/chat_item_other_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingVertical="12dp"
        android:paddingLeft="18dp"
        android:paddingRight="12dp"
        android:layout_marginStart="10dp"
        android:gravity="left|center"
        android:background="@drawable/wc_chat_other3_normal"
        android:visibility="visible"
        android:textColor="@color/black"
        android:textSize="18sp"
        android:text="1"/>
</RelativeLayout>
//发送文本
private fun sendMessage(chatBean: ChatBean){
    if(chatBean == null){
        ToastUtils.makeText(requireActivity(), "发送信息不能为空")
        return
    }
    var content = chatBean.content
    if(TextUtils.isEmpty(content)){
        ToastUtils.makeText(requireActivity(), "发送信息不能为空")
    } else {
        ChatManagerUtils.getInstance().sendMessage(toUserId, content)
        chat_content.setText("")
        CoroutineScope(Dispatchers.IO).launch {
            if(chatBean.contentType == ChatBean.CONTENT_TYPE_REDPACKET){
                var content = chatBean.content
                chatBean.content = CommonUtils.Chat.getRedpacket(content).toString()
            } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_TRANSFER){
                var content = chatBean.content
                chatBean.content = CommonUtils.Chat.getTransfer(content).toString()
            }
            ChatRepository.insertChat(chatBean)
        }
        refreshBase(chatBean)
    }
}


/**
 * 刷新发送、接收聊天信息
 * @param chatBean ChatBean
 */
private fun refreshBase(chatBean: ChatBean){
    CoroutineScope(Dispatchers.Main).launch {
        //chatViewModel.insertChat(chatBean)
        TagUtils.d("ChatFragment refreshBase 刷新聊天信息 ")
        adapter.refresh(chatBean)
        if(chatBean.contentType == ChatBean.CONTENT_TYPE_LOCATION){
            delay(200)
        }
        swipe_target.scrollToPosition(adapter.itemCount -1)
    }
}

 

/**
 * 使用xmpp发送文本信息
 * @param toUser String 发送用户id
 * @param content String
 */
fun sendMessage(toUser : String, content : String){
    CoroutineScope(Dispatchers.IO).launch {
        TagUtils.d("ChatManagerUtils 处理文本, ${toUser}, ${content} , ${getChat(toUser)}")
        var msg = Message()
        msg.body = content
        getChat(toUser)?.sendMessage(msg)
    }
}
//插入数据库
fun insertChat(chatBean: ChatBean) : Long {
    var chatListLocal = getAllChat()
    if(chatListLocal == null || chatListLocal.size < 1){
        return WcDatabase.getInstance(WcApp.getContext()).chatDao().insertChat(chatBean)
    }
    var resultList = chatListLocal.filter {
        it.messageId.equals(chatBean.messageId)
    }
    //过滤重复数据
    if(resultList.size > 0){
        return 0
    }
    return WcDatabase.getInstance(WcApp.getContext()).chatDao().insertChat(chatBean)
}

接收消息监听代码:

override fun chatCreated(chat: Chat, createdLocally: Boolean) {
    TagUtils.d("消息监听回调:chat = ${chat} , createdLocally = ${createdLocally}")
    if(!createdLocally){
        chat.addMessageListener { chat, message ->
            TagUtils.d("获取好友发来的信息 ${message.from} , ${message.to}, ${message.body}")
            var content = message.getBody()
            if(!TextUtils.isEmpty(content) && content.length > 0){
                var fromUser = BaseUtils.getChatAccountFrom(message.from)
                var toUser = BaseUtils.getChatAccount(message.to)
                var userType = ChatBean.USER_TYPE_OTHER

                if(content.startsWith(CommonUtils.Chat.LOCATION_MARK)){
                    //发送定位
                    //去掉location###标志
                    var remarkContent = CommonUtils.Chat.getLocation(content)
                    //使用逗号分隔符,分别读取经纬度
                    var contents = remarkContent.split(",")
                    var latitude = contents[0].toDouble()
                    var longitude = contents[1].toDouble()
                    var chatBean = CommonUtils.Chat.getChatBean(fromUser, toUser, userType, content, ChatBean.CONTENT_TYPE_LOCATION, "", latitude, longitude)
                    ChatRepository.insertChat(chatBean)
                    chatBean.isReceive = true
                    EventBus.getDefault().post(chatBean)
                } else if(content.startsWith(CommonUtils.Chat.REDPACKET_MARK)){
                    //发送红包, 去掉redpacket###写入数据库
                    content = CommonUtils.Chat.getRedpacket(content).toString()
                    var chatBean = CommonUtils.Chat.getChatBean(fromUser, toUser, userType, content, ChatBean.CONTENT_TYPE_REDPACKET, "",0.0, 0.0)
                    ChatRepository.insertChat(chatBean)
                    chatBean.isReceive = true
                    EventBus.getDefault().post(chatBean)
                } else if(content.startsWith(CommonUtils.Chat.VOICE_MARK)){
                    //发送语音, 去掉voice###写入数据库
                    content = CommonUtils.Chat.getMedia(content, CommonUtils.Chat.VOICE_MARK)
                    var chatBean = CommonUtils.Chat.getChatBeanVoiceServer(fromUser, toUser, userType,ChatBean.CONTENT_TYPE_VOICE, content,0)
                    chatBean.isReceive = true
                    processDownload(chatBean)
                } else if(content.startsWith(CommonUtils.Chat.VIDEO_MARK)){
                    //发送小视频, 去掉video###写入数据库
                    content = CommonUtils.Chat.getMedia(content, CommonUtils.Chat.VIDEO_MARK)
                    var chatBean = CommonUtils.Chat.getChatBeanVideoServer(fromUser, toUser, userType,ChatBean.CONTENT_TYPE_VIDEO, content,0)
                    chatBean.isReceive = true
                    processDownload(chatBean)
                } else if(content.startsWith(CommonUtils.Chat.IMAGE_MARK)){
                    //发送图片, 去掉image###写入数据库
                    content = CommonUtils.Chat.getMedia(content, CommonUtils.Chat.IMAGE_MARK)
                    var chatBean = CommonUtils.Chat.getChatBeanImageServer(fromUser, toUser, userType,ChatBean.CONTENT_TYPE_IMG, content,0)
                    chatBean.isReceive = true
                    processDownload(chatBean)
                } else if(content.startsWith(CommonUtils.Chat.TRANSFER_MARK)){
                    //发送转账, 去掉transfer###写入数据库
                    content = CommonUtils.Chat.getTransfer(content).toString()
                    var chatBean = CommonUtils.Chat.getChatBean(fromUser, toUser, userType, content, ChatBean.CONTENT_TYPE_TRANSFER, "",0.0, 0.0)
                    ChatRepository.insertChat(chatBean)
                    chatBean.isReceive = true
                    EventBus.getDefault().post(chatBean)
                } else if(content.startsWith(CommonUtils.QRCommon.QR_RECEIVE_CODE)){
                    //向个人发送收款
                    var balance = content.substring(CommonUtils.QRCommon.QR_RECEIVE_CODE.length, content.length)
                    TagUtils.d("MyChatManagerListener 向个人发送收款金额: ${fromUser} , ${toUser},  ${balance}")
                    updateBalanceServer(fromUser, toUser, CommonUtils.User.OPERATOR_PLUS, balance.toFloat())
                } else if(content.startsWith(CommonUtils.QRCommon.QR_PAYMENT_CODE)){
                    //向商家付款
                    var balance = content.substring(CommonUtils.QRCommon.QR_RECEIVE_CODE.length, content.length)
                    TagUtils.d("MyChatManagerListener 向商家付款金额: ${fromUser} , ${toUser}, ${balance}")
                    updateBalanceServer(fromUser, toUser, CommonUtils.User.OPERATOR_MINUS, balance.toFloat())
                } else {
                    var chatBean = CommonUtils.Chat.getChatBean(fromUser, toUser, userType, content, ChatBean.CONTENT_TYPE_TEXT, "",0.0, 0.0)
                    ChatRepository.insertChat(chatBean)
                    chatBean.isReceive = true
                    EventBus.getDefault().post(chatBean)
                }
                ChatNotificationUtils.sendNotification(fromUser)
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/45931.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

麦芽糖-阿奇霉素 maltose-Azithromycin 阿奇霉素-PEG-麦芽糖

麦芽糖-阿奇霉素 maltose-Azithromycin 阿奇霉素-PEG-麦芽糖 中文名称&#xff1a;麦芽糖-阿奇霉素 英文名称&#xff1a;maltose-Azithromycin 别称&#xff1a;阿奇霉素修饰麦芽糖&#xff0c;阿奇霉素-麦芽糖 纯度&#xff1a;95% 存储条件&#xff1a;-20C&#xff0c…

webscoket学习

webscoket基本使用 WebSocket - Web API 接口参考 | MDN 使用node编写webscoket服务 nodejs-webscoket 在github的地址↓ GitHub - sitegui/nodejs-websocket: A node.js module for websocket server and client ws和socket.io 是wbscket的两个库 仓库地址&#xff1a;l…

Scala系列-5、scala中的泛型、actor、akka

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 传送门&#xff1a;大数据系列文章目录 目录scala的 泛型给方法定义泛型给类定义泛型泛型的上下界泛型中 非变 协变 和 逆变scala中actor相关内…

echarts中tooltip设为渐变色与模糊背景滤镜

关于echarts各项内容&#xff08;包括图表面积区域&#xff09;设为渐变色已在上篇文章里全部阐述&#xff1a; echarts折线图与柱状图等绘成渐变色的方法 单独将tooltip拉出来再写一篇&#xff0c;是因为用formatter配合超文本的形式在echarts的配置项中&#xff0c;于自定义样…

Python使用magic判断文件MIME类型

文章目录官网安装使用判断文件的MIME类型支持中文的代码问题官网 GitHub - ahupp/python-magic: A python wrapper for libmagic 安装 pip install python-magic pip install python-magic-bin使用 判断文件的MIME类型 代码 # encodingutf-8 import magic #pip install pyt…

希尔贝壳受邀参加IEEE自动语音识别与理解研讨会-ASRU 2021

ASRU 2021 IEEE Automatic Speech Recognition and Understanding Workshop&#xff08;2021年IEEE自动语音识别与理解研讨会&#xff0c;以下简称ASRU&#xff09;&#xff0c;将于2021年12月13日至17日在哥伦比亚卡塔赫纳举行。 ASRU 研讨会是IEEE语音和语言处理技术委员会(…

领悟《信号与系统》之 周期信号的傅里叶变换计算

周期信号的傅里叶变换计算一、周期信号的傅里叶变换存在的条件二、周期信号的傅里叶变换例题&#xff1a;一、周期信号的傅里叶变换存在的条件 典型非周期信号&#xff08;如指数信号&#xff0c;矩形信号等&#xff09;都是满足绝对可积&#xff08;或绝对可和&#xff09;条…

IDEA的日常快捷键大全

更多内容在&#xff1a;https://javaxiaobear.gitee.io/ ​​​​​​第1组&#xff1a;通用型 说明 快捷键 复制代码-copy ctrl c 粘贴-paste ctrl v 剪切-cut ctrl x 撤销-undo ctrl z 反撤销-redo ctrl shift z 保存-save all ctrl s 全选-select all …

(2)点云库处理学习——剔除点云值

1、主要参考 1.1参考地址 (1) 点云离群点剔除 — open3d python_Coding的叶子的博客-CSDN博客_离群点去除 (2) open3d之点云异常值去除&#xff08;笔记5&#xff09;_Satellite_H的博客-CSDN博客 (3)斯坦福经典兔子的点云数据下载地址 下载地址 Model : Bunny 1.2兔子…

3D视觉识别案例:3D无序棒料抓取,阀体圆环上下料,电机定子上料

3D无序棒料抓取 某知名汽车行业 项目背景 长春某知名汽车行业&#xff0c;需求3D视觉实现圆形棒材的上料自动化。 作业流程 钢棒依次经过剪切/锯切下料&#xff0c;从深筐中抓取&#xff0c;先放置在V型二次定位平台上&#xff0c;再从平台抓到输送线上&#xff0c;目标工…

[附源码]SSM计算机毕业设计新冠疫苗线上预约系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

超算,先进计算未来的研究方向有哪些?

超算是一个非常有趣的方向&#xff0c;当人们仰天长望思索宇宙大爆炸和起源时&#xff0c;超算便成为了非常重要的一个研究途径&#xff0c;利用超算平台对中国FAST天眼射电望远镜捕捉到的海量信号进行分析和处理&#xff0c;帮助中科院探索发现了诸如脉冲星、最大原子气体、快…

如何将报告从 JasperReports 导入到 FastReport .NET?

FastReport.NET官方版下载 我们在 JasperReports 添加了一个新的导入功能&#xff0c;如果要使用它&#xff0c;需要到 FastReport .NET 设计器中的“文件”菜单并选择“打开...”。在出现的窗口中&#xff0c;选择过滤器“JasperReports 文件 (*.jrxml)”。所选文件将自动转换…

基于Apache-DButils以及Druid(德鲁伊)与数据库交互实现的一个项目:满汉楼

基于Apache-DButils以及Druid(德鲁伊)与数据库交互实现的一个项目&#xff1a;满汉楼 每博一文案 张小贤曾说过: 你不过是做自己喜欢做的事&#xff0c;过自己喜欢过的生活。 若有人因为你喜欢做的事而觉得恶心和取笑你&#xff0c;那是他们的事。是呀&#xff0c;生活是苦&am…

蓝海创意云亮相2022南京融交会,打造沉浸式元宇宙互动体验

11月24日&#xff0c;2022中国&#xff08;南京&#xff09;文化和科技融合成果展览交易会在南京国际展览中心正式开幕&#xff0c;展会聚焦文化数字化战略&#xff0c;集中展示文化数据专网、数字化公共文化服务、“元宇宙”等数字文化新基建、新服务、新场景、新体验。 苏州…

第十三章《集合》第3节:Set集合

Set也是Collection的子接口,它定义了另一种形式的集合,专业上称之为Set集合。Set集合的特点如图13-9所示。 图13-9 Set类型集合 从图13-9可以看出:Set类型的集合就像是一个装苹果的筐子,程序员只要把元素存入这个筐子即可。集合中的元素像是胡乱堆积在一起,因此元素没有索…

迷宫-蓝桥云课,python实现

X 星球的一处迷宫游乐场建在某个小山坡上。它是由 10 \times 101010 相互连通的小房间组成的。 房间的地板上写着一个很大的字母。我们假设玩家是面朝上坡的方向站立&#xff0c;则&#xff1a; LL 表示走到左边的房间&#xff0c;RR 表示走到右边的房间&#xff0c;UU 表示走…

HTTPS —— HTTPS的加密方式

JavaEE传送门JavaEE HTTP —— HTTP 协议中的细节(超详细!!) HTTP —— HTTP 响应详解, 构造 HTTP 请求 目录HTTPS"加密"对称加密非对称加密证书总结HTTPS “加密” 明文: 要传递的原始信息 密文: 经过加密后的信息 密钥: 将明文加密的方法 (在加密和解密中起到…

京东APP技术解密:移动端秒级配置触达平台-Switchquery

原文已同步发表在京东零售技术公众号:mp.weixin.qq.com/s/hvsFwsQHT… 一 背景 随着移动互联网的快速发展&#xff0c;为满足各类用户及人群的体验需求&#xff0c;移动端的开发者们开发了丰富多彩的体验与功能。同时对于快速控制各类功能的切换、灰度&#xff0c;降级等能力…

纠正一下网上文章所说“利用RPC绕过CFG”的错误说法

纠正误区 网上说“利用RPC绕过CFG”的说法是不正确的&#xff0c;我先给出自己的观点&#xff0c;后面再说我的分析。网上有好几篇分析CVE-2021-26411的文章&#xff0c;对绕过CFG一律都说是利用RPC。其实在这个漏洞场景下&#xff0c;攻击者只不过是借助RPC获得执行任意系统函…