143.[HarmonyOS NEXT 实战案例十:List系列] 字母索引列表组件实战:打造高效联系人应用 基础篇
[HarmonyOS NEXT 实战案例十:List系列] 字母索引列表组件实战:打造高效联系人应用 基础篇
项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star
效果演示
一、字母索引列表基础介绍
在HarmonyOS NEXT应用开发中,字母索引列表是一种常见的UI模式,特别适合展示按字母分类的数据,如联系人、城市列表等。通过结合ListItemGroup和AlphabetIndexer组件,我们可以创建一个既美观又高效的字母索引列表,提升用户查找体验。
1.1 字母索引列表的组成部分
组成部分 | 说明 |
---|---|
List | 基础列表容器,用于展示所有内容 |
ListItemGroup | 分组组件,用于按字母分组显示列表项 |
AlphabetIndexer | 字母索引器,显示在列表侧边,用于快速导航到对应字母分组 |
Scroller | 滚动控制器,用于控制列表滚动到指定位置 |
1.2 相关组件介绍
1.2.1 AlphabetIndexer组件
AlphabetIndexer是HarmonyOS NEXT提供的字母索引器组件,用于在列表旁边显示字母索引,支持用户通过点击或滑动快速定位到对应的列表位置。
主要属性 | 类型 | 说明 |
---|---|---|
arrayValue | string[] | 索引器中显示的字符数组 |
selected | number | 当前选中项的索引 |
color | ResourceColor | 索引器的颜色 |
selectedColor | ResourceColor | 选中项的颜色 |
popupColor | ResourceColor | 弹出提示的颜色 |
selectedBackgroundColor | ResourceColor | 选中项的背景颜色 |
itemSize | number | 索引项的大小 |
font | Font | 索引项的字体样式 |
selectedFont | Font | 选中项的字体样式 |
popupFont | Font | 弹出提示的字体样式 |
usingPopup | boolean | 是否使用弹出提示 |
alignStyle | IndexerAlign | 索引器的对齐方式 |
1.2.2 Scroller控制器
Scroller是HarmonyOS NEXT提供的滚动控制器,用于控制可滚动组件(如List)的滚动行为。
主要方法 | 说明 |
---|---|
scrollTo | 滚动到指定位置 |
scrollToIndex | 滚动到指定索引的项 |
scrollEdge | 滚动到边缘 |
scrollPage | 滚动一页 |
二、字母索引列表实战案例
2.1 需求分析
我们将实现一个按字母分组的联系人列表,包含以下功能:
- 联系人按首字母分组显示
- 每个分组有明显的标题
- 右侧显示字母索引器,支持快速导航
- 点击字母索引时,列表自动滚动到对应分组
- 列表滚动时,字母索引器同步更新选中状态
2.2 数据模型定义
首先,我们定义联系人和分组的数据模型:
interface ContactType {
name: string,
phone: string,
avatar?: Resource
}
interface AlphabetIndexerType {
key: string,
contacts: ContactType[]
}
然后,准备按字母分组的联系人数据:
private contactGroups:AlphabetIndexerType[] = [
{
key: 'A',
contacts: [
{ name: '艾伦', phone: '138-0000-0001', avatar: $r('app.media.big27') },
{ name: '安妮', phone: '138-0000-0002', avatar: $r('app.media.big26') },
{ name: '奥利弗', phone: '138-0000-0003', avatar: $r('app.media.big25') }
]
},
{
key: 'B',
contacts: [
{ name: '白露', phone: '138-0000-0004', avatar: $r('app.media.big24') },
{ name: '鲍勃', phone: '138-0000-0005', avatar: $r('app.media.big23') },
{ name: '贝蒂', phone: '138-0000-0006', avatar: $r('app.media.big22') }
]
},
// 其他字母分组...
]
2.3 获取索引字母数组
我们需要从联系人分组数据中提取所有的索引字母,用于AlphabetIndexer组件:
private get indexLetters(): string[] {
return this.contactGroups.map(group => group.key)
}
2.4 分组头部实现
接下来,我们实现分组的头部,显示字母标题:
@Builder
GroupHeader(key: string) {
Text(key)
.fontSize(20)
.fontWeight(FontWeight.Bold)
.backgroundColor('#F1F3F5')
.width('100%')
.padding({ left: 16, top: 8, bottom: 8 })
}
2.5 页面结构设计
整个页面采用Stack布局,包含主要内容和字母索引器两部分:
build() {
Stack({ alignContent: Alignment.TopEnd }) {
// 主要内容
Column() {
// 标题栏
Row() {
// 标题栏内容
}
// 联系人列表
List() {
// 列表内容
}
}
// 字母索引器
AlphabetIndexer() {
// 索引器配置
}
}
}
2.6 标题栏实现
标题栏包含标题文本和操作按钮:
Row() {
Text('联系人')
.fontSize(24)
.fontWeight(FontWeight.Bold)
Blank()
Image($r('app.media.01'))
.width(24)
.height(24)
.margin({ right: 16 })
Image($r('app.media.02'))
.width(24)
.height(24)
.margin({ right: 16 })
}
.width('100%')
.height(56)
.padding({ left: 16 })
.backgroundColor('#F1F3F5')
2.7 联系人列表实现
联系人列表使用List和ListItemGroup组件,按字母分组显示联系人:
private scroller: Scroller = new Scroller() // 滚动控制器
@State currentIndex: number = 0 // 当前索引
// 联系人列表
List({ scroller: this.scroller }) {
ForEach(this.contactGroups, (group:AlphabetIndexerType, groupIndex) => {
ListItemGroup({
header: this.GroupHeader(group.key),
space: 0
}) {
ForEach(group.contacts, (contact:ContactType) => {
ListItem() {
Row() {
// 头像
Image(contact.avatar || $r('app.media.big1'))
.width(40)
.height(40)
.borderRadius(20)
.margin({ right: 16 })
// 联系人信息
Column() {
Text(contact.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
Text(contact.phone)
.fontSize(14)
.fontColor('#666666')
.margin({ top: 4 })
}
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.padding({ left: 16, right: 16, top: 12, bottom: 12 })
}
.height(64)
})
}
})
}
.width('100%')
.layoutWeight(1)
.onScrollIndex((firstIndex: number) => {
// 更新当前索引
this.currentIndex = firstIndex
})
.divider({ // 设置分割线
strokeWidth: 1,
color: '#E5E5E5',
startMargin: 72,
endMargin: 16
})
2.8 字母索引器实现
最后,我们实现字母索引器,并处理索引选择事件:
AlphabetIndexer({
arrayValue: this.indexLetters,
selected: this.currentIndex
})
.itemSize(16) // 字母大小
.font({ size: 14 }) // 字体大小
.selectedFont({ size: 16, weight: FontWeight.Bold }) // 选中字体样式
.popupFont({ size: 30, weight: FontWeight.Bold }) // 弹出字体样式
.selectedBackgroundColor('#007DFF') // 选中背景色
.popupColor('#CCCCCC') // 弹出颜色
.usingPopup(true) // 使用弹出效果
.alignStyle(IndexerAlign.Right) // 右侧对齐
.margin({ right: 8 })
.onSelect((index: number) => {
// 滚动到对应索引位置
this.currentIndex = index
this.scroller.scrollToIndex(index)
})
三、完整代码解析
@Component
export struct AlphabetIndexerList {
private scroller: Scroller = new Scroller() // 滚动控制器
@State currentIndex: number = 0 // 当前索引
// 按字母分组的联系人数据
private contactGroups:AlphabetIndexerType[] = [
// 数据定义(同上)
]
// 获取所有索引字母
private get indexLetters(): string[] {
return this.contactGroups.map(group => group.key)
}
// 构建分组头部
@Builder
GroupHeader(key: string) {
// 头部实现(同上)
}
build() {
Stack({ alignContent: Alignment.TopEnd }) {
Column() {
// 标题栏
Row() {
// 标题栏实现(同上)
}
// 联系人列表
List({ scroller: this.scroller }) {
// 列表实现(同上)
}
}
.width('100%')
.height('100%')
// 字母索引器
AlphabetIndexer({
// 索引器实现(同上)
})
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
3.1 代码结构分析
部分 | 说明 |
---|---|
数据模型 | 定义ContactType和AlphabetIndexerType接口,描述联系人和分组的数据结构 |
数据准备 | 创建contactGroups数组,包含按字母分组的联系人数据 |
索引字母 | 通过indexLetters计算属性获取所有索引字母 |
构建器 | 定义GroupHeader构建器,用于创建分组的头部 |
页面结构 | 使用Stack作为根容器,包含主要内容和字母索引器 |
联系人列表 | 使用List和ListItemGroup创建分组列表,每个分组包含多个ListItem |
字母索引器 | 使用AlphabetIndexer创建字母索引器,处理索引选择事件 |
3.2 关键技术点分析
3.2.1 List与Scroller的结合使用
通过将Scroller实例传递给List组件,我们可以在外部控制列表的滚动行为:
private scroller: Scroller = new Scroller()
List({ scroller: this.scroller }) {
// 列表内容
}
3.2.2 onScrollIndex事件处理
通过监听List的onScrollIndex事件,我们可以获取当前显示的第一个项的索引,用于更新字母索引器的选中状态:
.onScrollIndex((firstIndex: number) => {
this.currentIndex = firstIndex
})
3.2.3 AlphabetIndexer与List的联动
通过AlphabetIndexer的onSelect事件和Scroller的scrollToIndex方法,我们实现了字母索引器与列表的联动:
.onSelect((index: number) => {
this.currentIndex = index
this.scroller.scrollToIndex(index)
})
3.2.4 Stack布局的使用
使用Stack布局可以将字母索引器叠加在主要内容上,并通过alignContent属性控制其位置:
Stack({ alignContent: Alignment.TopEnd }) {
// 主要内容
// 字母索引器
}
总结
在本篇教程中,我们学习了如何使用HarmonyOS NEXT的ListItemGroup和AlphabetIndexer组件创建一个字母索引列表。我们从数据模型定义、分组头部实现、页面结构设计到联系人列表和字母索引器实现,全面讲解了字母索引列表的实现过程。
- 0回答
- 4粉丝
- 0关注
- 144.[HarmonyOS NEXT 实战案例十:List系列] 字母索引列表组件实战:打造高效联系人应用 进阶篇
- [HarmonyOS NEXT 实战案例六:List系列] 垂直列表组件实战:打造高效联系人列表 基础篇
- 134.[HarmonyOS NEXT 实战案例六:List系列] 垂直列表组件实战:打造高效联系人列表 进阶篇
- [HarmonyOS NEXT 实战案例三:SideBarContainer] 侧边栏容器实战:社交应用联系人列表 基础篇
- 139.[HarmonyOS NEXT 实战案例八:List系列] 滑动操作列表组件实战:打造高效待办事项应用 基础篇
- [HarmonyOS NEXT 实战案例三:SideBarContainer] 侧边栏容器实战:社交应用联系人列表 进阶篇
- 149.[HarmonyOS NEXT 实战案例十一:List系列] 下拉刷新和上拉加载更多列表组件实战:打造高效新闻应用 基础篇
- 137.[HarmonyOS NEXT 实战案例七:List系列] 多列列表组件实战:打造精美应用推荐页 基础篇
- 151.[HarmonyOS NEXT 实战案例十二:List系列] 卡片样式列表组件实战:打造精美电商应用 基础篇
- 141.[HarmonyOS NEXT 实战案例九:List系列] 分组列表组件实战:打造分类设置菜单 基础篇
- 140.[HarmonyOS NEXT 实战案例八:List系列] 滑动操作列表组件实战:打造高效待办事项应用 进阶篇
- 150.[HarmonyOS NEXT 实战案例十一:List系列] 下拉刷新和上拉加载更多列表组件实战:打造高效新闻应用 进阶篇
- 135.[HarmonyOS NEXT 实战案例七:List系列] 水平列表组件实战:打造精美图片库 基础篇
- 147.[HarmonyOS NEXT 实战案例八 :List系列] 粘性头部列表基础篇
- 155.[HarmonyOS NEXT 实战案例十二 :List系列] 聊天消息列表 - 基础篇