HarmonyOS鸿蒙NEXT应用元服务常见列表操作分组吸顶场景
HarmonyOS鸿蒙NEXT应用元服务常见列表操作分组吸顶场景
分组吸顶场景
场景描述
双列表同向联动,右边字母列表用于快速索引,内容列表根据首字母进行分组,常用于通讯录、城市选择、分组选择等页面。
本场景以城市列表页面为例,左侧城市列表数据和右侧字母导数据通过List组件来展示,并通过Stack组件使两个列表数据分层显示。在进入页面后,通过滑动左侧城市列表数据,列表字母标题吸顶展示,对应右侧字母导航内容高亮显示;点击右侧字母导航内容,左侧城市列表展示对应内容。
实现原理
左侧List作为城市列表,右侧List为城市首字母快捷导航列表,通过ListItem对对应数据进行渲染展示,并使用Stack堆叠容器组件,字母导航列表覆盖城市列表上方,再给对应List添加sticky
属性和onScrollIndex()
方法,实现两个列表数据间的联动效果。
开发步骤
城市列表使用ListItemGroup,对“当前城市”“热门城市”“城市数据”进行分组,并通过ListItem展示每个分组中的具体数据。
城市列表代码示例
// List data content.
@Builder
textContent(content: string) {
Text(content)
// ...
}
CityList.ets
List({ scroller: this.cityScroller }) {
// Current city.
ListItemGroup({ header: this.itemHead($r('app.string.current_city')) }) {
ListItem() {
Text(this.currentCity)
.width('100%')
.height(45)
.fontSize(16)
.padding({ left: 16, top: 12, bottom: 12 })
.textAlign(TextAlign.Start)
.backgroundColor(Color.White)
}
}
// Popular cities.
ListItemGroup({ header: this.itemHead($r('app.string.popular_cities')) }) {
ForEach(this.hotCities, (item: string) => {
ListItem() {
textContent(item);
}
}, (item: string) => item)
}
.divider({
strokeWidth: 1,
color: '#EDEDED',
startMargin: 10,
endMargin: 45
})
// City data.
ForEach(this.groupWorldList, (item: string) => {
// Traverse the first letter of the city and use it as the header of the city grouping data.
ListItemGroup({ header: this.itemHead(item) }) {
// Retrieve and display corresponding city data based on letters.
ForEach(this.getCitiesWithGroupName(item), (cityItem: City) => {
ListItem() {
textContent(cityItem.city);
}
}, (cityItem: City) => cityItem.city)
}
})
}
右侧字母导航列表数据,同样通过List组件进行展示。
字母导航列表代码示例
// Side letter navigation data.
Column() {
List({ scroller: this.navListScroller }) {
ForEach(this.groupWorldList, (item: string, index: number) => {
ListItem() {
Text(item)
// ...
}
}, (item: string) => item)
}
}
使用堆叠容器组件Stack,将字母导航内容覆盖到城市列表内容上方。
Stack 组件示例
Stack({ alignContent: Alignment.End }) {
// City List Data.
List({ scroller: this.cityScroller }) {
// ...
}
// ...
// Side letter navigation data.
Column() {
List({ scroller: this.navListScroller }) {
// ...
}
}
// ...
}
最后,给城市列表添加sticky
属性实现标题吸顶效果,及添加onScrollIndex()
方法,通过selectNavIndex
变量与字母导航列表内容进行关联,控制的对应字母导航内容的选中状态。
Scroll 管理示例
Stack({ alignContent: Alignment.End }) {
// City List Data.
List({ scroller: this.cityScroller }) {
// ...
}
// ...
.onScrollIndex((index: number) => {
// By linking the selectNavIndex state variable with index, control the selection status of the navigation list.
this.selectNavIndex = index - 2;
})
// Side letter navigation data.
Column() {
List({ scroller: this.navListScroller }) {
ForEach(this.groupWorldList, (item: string, index: number) => {
ListItem() {
Text(item)
// ...
.onClick(() => {
this.selectNavIndex = index;
// Select the navigation list and set isClickScroll to true to prevent changes in the navigation list status during the scrolling process with the city list.
this.isClickScroll = true;
// By using the scrollIndex method of cityScanner, control the sliding city list to specify the Index,
// as there are "current city" and "popular city" in the city list, so the index needs to be incremented by 2.
this.cityScroller.scrollToIndex(index + 2, false, ScrollAlign.START);
})
}
}, (item: string) => item)
}
}
// ...
}
实现效果
本文主要引用整理于鸿蒙官方文档
更多关于HarmonyOS鸿蒙NEXT应用元服务常见列表操作分组吸顶场景的实战教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙NEXT中实现列表分组吸顶效果主要使用List组件的sticky属性。在ArkUI中,通过设置List的sticky属性为StickyStyle.Header,可使分组头部在滚动时吸附顶部。示例代码:
@Component
struct GroupList {
@State data: Array<GroupData> = [...]
build() {
List({ space: 12 }) {
ForEach(this.data, (group) => {
ListItem() {
Text(group.header).sticky(StickyStyle.Header)
ForEach(group.items, (item) => {
ListItem() {
Text(item)
}
})
}
})
}
}
}
需确保List组件外层容器高度固定,List设置宽高为100%。数据源需包含分组header和items的层级结构。
更多关于HarmonyOS鸿蒙NEXT应用元服务常见列表操作分组吸顶场景的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS NEXT中实现分组吸顶效果,关键点如下:
- 使用ListItemGroup进行数据分组,通过header属性设置分组标题
- 为List组件添加sticky属性实现吸顶效果
- 通过Stack组件叠加两个List实现布局
- 联动控制:
- 左侧列表使用onScrollIndex监听滚动位置
- 右侧导航列表通过scrollToIndex控制左侧定位
- 使用selectNavIndex状态变量同步高亮状态
核心代码示例:
List({ scroller: this.cityScroller }) {
ListItemGroup({ header: this.itemHead('A') }) {
// 分组内容
}
.sticky(StickyStyle.Header) // 关键吸顶属性
}
.onScrollIndex((index) => {
this.selectNavIndex = index - 2; // 同步右侧高亮
})
右侧导航点击处理:
.onClick(() => {
this.cityScroller.scrollToIndex(index + 2); // 定位到对应分组
})
这种实现方式性能较好,适合通讯录等长列表场景,注意处理好分组索引的偏移计算。