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

鸿蒙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++

}

})

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

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

@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》文章获取。

相关推荐

《诗经·氓》原文注解与大意翻译
电脑故障最大元凶 曝主板为何容易坏
Denon(天龙) AVR-1713功放(过往型号)