HarmonyOS实战:腾讯IM之聊天详情页面搭建(二)

前言

鸿蒙版本腾讯 IM 的聊天功能十分复杂,需要开发者手动实现整个聊天对话的业务代码,这对开发者来说是个不小的挑战。本篇文章先从最基础的聊天对话列表开始教你一步一步实现完整的聊天功能,建议点赞收藏!

实现效果

先看本文最终的基本实现效果。

alt

需求分析

  • 对话列表左右排列
  • 支持发送文本消息
  • 支持实时接收消息
  • 支持拉取历史消息

技术实现

获取历史消息

  1. 当从会话列表进入聊天详情页面时,首先拉取最新历史消息。可以通过设置参数指定获取最近时长的历史消息,这里默认设置拉取最近一天的数据。
  let option: V2TIMMessageListGetOptio 
    option = {
        getType: V2TIMMessageGetType.V2TIM_GET_CLOUD_OLDER_MSG,
        userID: this.userId,
        count: 15,
        getTimeBegin: this.messageData!=undefined&&this.messageData.totalCount()>0 ? this.messageData.getDataAll()[0].timestamp:new Date().getTime(),
        getTimePeriod: 60 * 60 * 24000
      };
 V2TIMManager.getMessageManager().getHistoryMessageList(option)
      .then((messageList: V2TIMMessage[]) => {
        
      })

展示聊天列表

  1. 得到历史消息数据后,需要将数据绘制到页面上,同时注意对方和自己消息布局的排列。这里是使用 List 作为展示控件,同时使用鸿蒙原生的懒加载 LazyForEach 进行布局。
 List({ scroller: this.scroller }) {

      LazyForEach(this.messageData, (item: V2TIMMessage, index: number) => {
        ListItem() {
          this.ItemLayout(item)
        }
      }, (item: V2TIMMessage, index: number) => item.timestamp + "")

    }

注意 LazyForEach 的 键值使用的是消息体的时间戳。

  1. 接着绘制 item 的布局页面,先绘制对方的 UI 布局,通过消息体提供的 isSelf 字段判断当前消息是不是自己发的,以此将对话布局显示在左侧。
 Row{
   Flex({ justifyContent: this.message.isSelf ? FlexAlign.End : FlexAlign.Start, direction: FlexDirection.Row })
     {
         if (!this.message.isSelf) {
           Image(this.message?.faceURL)
             .alt($r("app.media.head_default"))
             .flexShrink(0)
         }
    Text(this.getMessageForType(this.message))
                   
 }

更新实时消息

当对方发送新的消息时,需要及时更新到消息列表中显示,要实现实时消息的更新需要增加消息监听回调。

/**
   * 实时消息监听
   */
  advancedMsgListener: V2TIMAdvancedMsgListener = {
    onRecvNewMessage: (message: V2TIMMessage) => {
      if (message!=undefined&&message.userID == this.userId) {
        this.messageData.pushData(message)
        this.scroller.scrollEdge(Edge.Bottom)
        IMListViewModel.cleanConversationUnreadMessageCount(message.userID)
      }
    },
    onReceviceMessageRevoked: (msgID: string, operateUser: V2TIMUserFullInfo, reason: string) => {
        let result = this.messageData.getDataAll().filter((item) => {
          return msgID == item.msgID
        })
        if (result.length > 0) {
          let index = this.messageData.getDataAll().indexOf(result[0])
          this.messageData.deleteData(index)
          result[0].status = V2TIMMessageStatus.V2TIM_MSG_STATUS_LOCAL_REVOKED
          this.messageData.addData(index, result[0])
        }
    }

  }



MessageTestInterfaces.addAdvancedMsgListener(this.advancedMsgListener)

发送文本消息

实现完消息的展示之后,需要实现文本消息的发送,调用 IM SDK 提供的sendC2CTextMessage方法创建本地文本消息,然后发送即可。

 let sendMessage = V2TIMManager.getMessageManager().createTextMessage(text)
    if (sendMessage == null || sendMessage.status == V2TIMMessageStatus.V2TIM_MSG_STATUS_SENDING) {
      return
    }
    sendMessage.isSelf = true
    sendMessage.elemType = V2TIMElemType.V2TIM_ELEM_TYPE_TEXT
    sendMessage.timestamp = new Date().getTime()
    sendMessage.nickName = //用户名称
    sendMessage.faceURL =  //用户头像
    sendMessage.status = V2TIMMessageStatus.V2TIM_MSG_STATUS_SENDING
    let textContent = new V2TIMTextElem()
    textContent.text = text
    sendMessage.textElem = textContent
    this.inputContent = ""
    const result = V2TIMManager.getInstance().sendC2CTextMessage(text, this.userId);

总结

本篇文章通过实际案例讲叙搭建一个聊天详情的基本实现思路。主要涉及历史消息的获取,实时消息的刷新,和文本消息的发送。接下来需要增加消息撤回,消息删除,发送失败等消息状态的实现。已经学会了的小伙伴,赶快动手试试吧!

#HarmonyOS##鸿蒙#
全部评论

相关推荐

初级前端工程师,9-12k。避雷❗️❗️文字偏长,前端伙伴留。初面是线上,女面试官,疯狂问八股文。问到微信小程序说适配问题,我回答了像rpx,rem,vw和vh计算单位,利用获取屏幕高度宽度,用@media判断手机平板等。然后她问我你没用过epx单位吗,当时我就懵逼了,我确实没听说过。我说这可能是你们公司项目里面自己封装的单位吧,她说肯定有的你可以结束之后去百度看一看。面试结束之后我去百度了,也问了AI工具,查无此计算单位。复试更是离谱,复试去的线下。要说初面是关于前端的技术,复试已经不知道在面试什么了。开始上来就问栈,队列,二叉树一些数据结构。(我目前是毕业了一年多,加上实习共工作了两年,也都是前端的工作,确实对这些大学学的知识遗忘了)只回答了栈后进先出,队列先进先出。第二个问题是前端哪些地方要用到数据结构,我说数组和集合他都说这些太简单了,我让他举例子,他和我说上传图片需要用到哪些数据结构,我说了队列和数组,要记录好顺序,文件名称,大小,类型等。他和我说这也不算,我直接说我不知道让他回答,他和我说了一个图片的压缩。当时我就纳闷了,图片压缩要什么数据结构,我实在想不出来我就问他他也不回答。下一个问题是上传三个文件abc,如果只要c文件,那么a和b文件就会导致冗余,该怎么删除a和b。我说导致冗余的话那肯定是上传到服务器的桶里了,需要前后端配合,前端在传文件的时候可以在名称也可以在formdata上添加参数,例如表格的id,或者随机不唯一数,后端接收到之后根据参数执行是否覆盖。他就开始了,他说前端不允许携带任何参数该怎么实现,纯前端和纯后端怎么解决,我没回答上来了,我问他怎么实现他也不说。他又和我扯说桶是什么东西,他说我讲到现在他对桶的概念还是不懂。我说桶是对象存储,可以放置静态文件或前端打包后的文件放进的地方。他说他懂了,就是服务器上的文件夹…我说你要这么理解那也可以,他开始和我说桶是一些ui界面那些文件夹画的像桶,所以你们这么叫桶。我说你是没用过阿里云或者腾讯云吗,上面的bucket你不了解吗,他就开始打断话题说好好好你要和我扯这个也行。(起码我个人来讲,包括我自己搭建的云服务器还是目前公司的云产品来说,bucket是很常用的功能)避雷❗️❗️
查看6道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务