鸿蒙Harmony开发实现联系人列表(仿微信通讯录)

先看效果

在这里插入图片描述

直入主题

UI结构

Stack帧结构容器+List联系人列表+AlphabetIndexer字母索引器

实现代码

1. 先定义好假数据

  • 通讯录列表数据
private dataList: any = [
    {
      title: '',
      contactList: [
        { name: "新的朋友", head: $r("app.media.ic_new_friend") },
        { name: "群聊", head: $r("app.media.ic_group_chat") },
        { name: "标签", head: $r("app.media.ic_tag") },
        { name: "公众号", head: $r("app.media.ic_official_account") }
      ]
    },
    {
      title: 'A',
      contactList: [
        { name: "ArdWard", head: $r("app.media.ic_user_head2") },
        { name: "阿联酋", head: $r("app.media.ic_user_head3") },
        { name: "艾森宝", head: $r("app.media.ic_user_head6") }
      ]
    },
 .....忽略中间数据
    {
      title: 'Z',
      contactList: [
        { name: "猪八戒", head: $r("app.media.ic_user_head3") },
        { name: "张宇恒", head: $r("app.media.ic_user_head4") },
        { name: "周大年", head: $r("app.media.ic_user_head5") }
      ]
    }
  ]
  • 字母索引器列表数据
private letterList: string[] = ['↑', '☆', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '#']

2. 再进行UI开发

从上文dataList数据结构里可以看出,我做了List嵌套List结构方式以适用通讯录中大组标签(A,B,C…)和它们各自的联系人列表,好在鸿蒙原生组件也支持了这样的列表模式:

List(整体列表)  --> ListItemGroup(A,B,C...组标签)  ---> ListItem(联系人列表)
  • 那么直接代码实现列表:
build() {
    Stack({ alignContent: Alignment.End }) {

      Column() {
        // 标题栏
        WechatToolbar({ title: "通讯录" })
        // 通讯录列表
        List({ scroller: this.scroller }) {
        // 遍历循环大组标签
          ForEach(this.dataList, (item) => {
            // 大组标签
            ListItemGroup({ header: this.itemHead(item.title) }) {
              // 遍历循环大组内的联系人列表
              ForEach(item.contactList, (contact) => {
                // 小组联系人列表
                ListItem() {
                  ListContactItem({ head: contact.head, name: contact.name })
                }
                .onClick(()=>{
                  router.pushUrl({ url: 'pages/chat/ChatPage',
                    params: { name: contact.name}
                  })
                })
              })
            }
            .divider({ strokeWidth: 0.8, color: '#f0f0f0', startMargin: 85, endMargin: 0 }) // 每行之间的分界线
          })
        }
        .width('100%')
        .height(0)
        .layoutWeight(1)
        .backgroundColor(Color.White)
      }
      .width("100%")
      .height("100%")

    ...... 忽略部分代码

    }.width("100%")
    .height("100%")

}
  
  
@Builder itemHead(title: string) {
    Text(title)
      .fontSize(14)
      .visibility("" === title ? Visibility.None : Visibility.Visible)
      .backgroundColor("#EDEDED")
      .height(36)
      .width("100%")
      .padding({ left: 20 })
}
  • 字母索引器也有原生组件支持,直接看实现代码:
AlphabetIndexer({ arrayValue: this.letterList, selected: 0 })
        .color(Color.Black)
        .font({ size: 14 })
        .selectedFont({ size: 14 })
        .selectedColor(Color.Black)
        .selectedBackgroundColor(Color.Transparent)
        .usingPopup(true)
        .popupColor(Color.White)
        .popupBackground("#57be6a")
        .popupFont({ size: 32, weight: FontWeight.Bolder })
        .itemSize(20)
        .alignStyle(IndexerAlign.Right)
        .margin({ top: 80 })
        .onSelect((index: number) => {
          let letter = this.letterList[index]
          var target: number = 0
          for (const item of this.dataList) {
            if (letter === item.title) {
              this.scroller.scrollToIndex(target)
              prompt.showToast({ message: "" + target })
              break
            }
            target++
          }
    })

关键点在于AlphabetIndexeronSelect事件中利用Listscroller进行滚动锚定,即:点击索引器的任意字母,联系人列表会自动跟着同步滚动。

最后贴下联系人自定义组件代码:

@Preview
@Component
export default struct ListContactItem {
  private head: string | PixelMap | Resource
  private name: string

  build() {
    Row() {
      Image(this.head)
        .width(46)
        .height(46)
        .borderRadius(4)
        .margin({ left: 20, right: 15 })
        .objectFit(ImageFit.Cover)

      Text(this.name)
        .fontSize(19)
        .fontWeight(500)
        .width("100%")
        .layoutWeight(1)
        .maxLines(1)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .margin({ right: 30 })
        .fontColor(Color.Black)
    }
    .backgroundColor(Color.White)
    .width("100%")
    .height(60)
  }
}

最后大功告成,需要完整源码的童鞋可跟进《鸿蒙(HarmonyOS)ArkTs版微信APP》文章获取。

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值