定制会话列表界面

更新时间: 2024/10/10 10:55:47

网易云信 IM UIKit 的会话列表模块(convesationkit-ui)提供会话列表界面(UI)的自定义配置项,助您快速实现该界面的 UI 个性化定制。

实现方式

自定义会话列表 UI,可以在(ConversationPage.ets)中直接修改源码,从而实现您所需的 UI 风格。

自定义范畴

会话列表界面中,支持自定义的 UI 元素包括但不限于标题栏、图标、会话头像、会话名称、会话时间、消息缩略内容等。如下图所示:

自定义示例

示例一:定制标题栏

标题栏源码在 ConversationPage.ets 中。

TypeScript   build() {
    Column({ space: 10 }) {
      Row() {
        //标题栏左侧图标
        Image($r('app.media.brand'))
          .margin({ left: 20 })
          .width(32)
          .height(32)
          .objectFit(ImageFit.Contain)
        //标题栏左侧文字
        Text($r('app.string.conversation_title'))
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .height(32)
          .width('100%')
          .margin({ left: 12, right: 12 })
          .layoutWeight(2)
          .textAlign(TextAlign.Start)
          .maxLines(1)
          .textOverflow({ overflow: TextOverflow.Ellipsis })

        Row()
          .height(1)
          .layoutWeight(1)

        //标题栏右侧搜索图标
        Image($r('app.media.nav_search'))
          .width(32)
          .height(32)
          .padding({
            left: 3,
            right: 3,
            top: 3,
            bottom: 3
          })
          .margin({ right: 10 })
          .onClick(() => {
            //单击去搜索
            this.goSearchPage(this.pathStack)
          })

        //标题栏右侧更多按钮图标
        Image($r('app.media.nav_add'))
          .width(32)
          .height(32)
          .padding({
            left: 3,
            right: 3,
            top: 3,
            bottom: 3
          })
          .margin({ right: 20 })
          .onClick(() => {
            this.conversationPopupShowed = !this.conversationPopupShowed
          })
          .bindPopup(this.conversationPopupShowed,
            //右侧更多操作弹框
            {
              targetSpace: 'popupLocation',
              builder: this.popupBuilder,
              placement: Placement.Bottom,
              mask: true,
              popupColor: Color.White,
              enableArrow: false,
              showInSubWindow: false,
              autoCancel: true,
              onStateChange: (e) => {
                if (!e.isVisible) {
                  this.conversationPopupShowed = false
                }
              }
            })

      }
      .height(55)
      .alignSelf(ItemAlign.Start)

      Row()
        .width('100%')
        .height(1)
        .backgroundColor("#E9EFF5")
    }
    .height('100%')
    .width('100%')
  }

示例二:标题栏右侧单击弹框

更多弹框按钮逻辑源码在 ConversationPage.ets 中。

TypeScript @Builder
  popupBuilder() {
    Column({ space: 16 }) {
      //添加好友
      Row() {
        Image($r('app.media.friend_add'))
          .width(14)
          .height(14)
        Text($r('app.string.add_friend'))
          .fontSize(14)
          .fontColor('#ff333333')
          .margin({ left: 6 })
      }.onClick(() => {
        if (this.conversationPopupShowed) {
          this.conversationPopupShowed = false
          this.goAddFriend(this.pathStack)
        }
      })

      //创建讨论组
      Row() {
        Image($r('app.media.team_discuss'))
          .width(14)
          .height(14)
        Text($r('app.string.create_discuss_team'))
          .fontSize(14)
          .fontColor('#ff333333')
          .margin({ left: 6 })
      }.onClick(() => {
        if (this.conversationPopupShowed) {
          this.conversationPopupShowed = false
          this.goToPersonSelectPage(this.pathStack, true)
        }
      })

      //创建高级群
      Row() {
        Image($r("app.media.team_advance"))
          .width(14)
          .height(14)
        Text($r('app.string.create_advance_team'))
          .fontSize(14)
          .fontColor('#ff333333')
          .margin({ left: 6 })
      }.onClick(() => {
        if (this.conversationPopupShowed) {
          this.conversationPopupShowed = false
          this.goToPersonSelectPage(this.pathStack, false)
        }
      })
    }
    .width(122)
    .padding({
      top: 16,
      left: 16,
      bottom: 16
    })
    .alignItems(HorizontalAlign.Start)
    .borderRadius(8)
    .backgroundColor('#ffFFFFFF')
  }

示例三:自定义会话 Item

源码在 ConversationViewItem 中。

TypeScript  build() {
    if (this.conversationInfo !== null) {
      Row() {
        //头像
        Stack({
          alignContent: Alignment.TopEnd
        }) {
          CommonAvatar({
            item: new AvatarItem(this.conversationInfo.avatar,
              this.getAvatarShowName(this.conversationInfo.name ?? ''),
              AvatarColorUntil.getBackgroundColorById(
                ChatKitClient.nim.conversationIdUtil
                  .parseConversationTargetId(this.conversationInfo.conversationId)
              ))
          })
          //未读数显示
          if (this.conversationInfo.mute !== true && this.conversationInfo.unreadCount > 0) {
            Text(this.getUnreadCountStr(this.conversationInfo.unreadCount))
              .fontSize(12)
              .fontColor('#ffFFFFFF')
              .textAlign(TextAlign.Center)
              .backgroundColor('#ffF24957')
              .borderRadius(20)
              .height(18)
              .width(18 + (this.getUnreadCountStr(this.conversationInfo.unreadCount).length - 1) * 4)
          }

        }
        .width(42)
        .height(42)

        Column() {
          //item 显示名称
          Text(this.conversationInfo.name)
            .fontSize(16)
            .fontColor("#ff333333")
            .textOverflow({ overflow: TextOverflow.Ellipsis })
            .maxLines(1)
            .margin({
              bottom: 8
            })

          //item 最后一条消息显示
          Text(this.getConversationContent(this.conversationInfo))
            .fontSize(13)
            .maxLines(1)
            .fontColor("#ff999999")
            .textOverflow({ overflow: TextOverflow.Ellipsis })
            .width(this.conversationInfo.mute ? '80%' : '100%')
        }
        .width('60%')
        .margin({
          left: 12,
          right: 12
        }).alignItems(HorizontalAlign.Start)

        //时间戳和 mute
        Column() {
          Text(this.formatTimestamp(this.conversationInfo.lastMessage?.messageRefer?.createTime ??
          this.conversationInfo.updateTime))
            .fontColor('#ffCCCCCC')
            .fontSize(12)
            .alignSelf(ItemAlign.End)
            .margin({
              bottom: 8
            })

          //mute 状态显示
          if (this.conversationInfo.mute) {

            Image($r('app.media.conversation_mute'))
              .width(14)
              .height(14)
          }
        }
        .width('20%')
        .margin({
          right: 12
        }).alignItems(HorizontalAlign.End)

      }
      .width('100%')
      .height(62)
      .onClick(() => {
        // this.goToChatPage()
        if (this.onItemClick !== undefined) {
          this.onItemClick()
        }
      })
      .backgroundColor(this.conversationInfo.stickTop ? '#ffF3F5F7' : '#ffffffff')
      .gesture(
        // 绑定可以重复触发的 LongPressGesture
        LongPressGesture({ repeat: true })
          .onAction((event: GestureEvent) => {
            if (!event.repeat) {
              //show 操作弹框
              this.dialogController.open()
            }
          })
          .onActionEnd(() => {
            //do nothing
          })
      )
      .padding({
        left: 20,
        top: 10,
        bottom: 10,
        right: 20
      })
    }

  }
此文档是否对你有帮助?
有帮助
去反馈
  • 实现方式
  • 自定义范畴
  • 自定义示例
  • 示例一:定制标题栏
  • 示例二:标题栏右侧单击弹框
  • 示例三:自定义会话 Item