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) } } } }