Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。
Kotlin高仿微信-项目实践58篇,点击查看详情
效果图:
详细的聊天功能请查看Kotlin高仿微信-第8篇-单聊,这里是提示文本功能的部分实现。
实现代码:
我的布局
<RelativeLayoutandroid: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.AppCompatTextViewandroid: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>
好友的布局:
<RelativeLayoutandroid: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.AppCompatTextViewandroid: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.contentif(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.contentchatBean.content = CommonUtils.Chat.getRedpacket(content).toString()} else if(chatBean.contentType == ChatBean.CONTENT_TYPE_TRANSFER){var content = chatBean.contentchatBean.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 = contentgetChat(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_OTHERif(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 = trueEventBus.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 = trueEventBus.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 = trueprocessDownload(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 = trueprocessDownload(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 = trueprocessDownload(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 = trueEventBus.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 = trueEventBus.getDefault().post(chatBean)}ChatNotificationUtils.sendNotification(fromUser)}}} }