鸿蒙HarmonyOS开发中列表(List)组件的全面解析
鸿蒙HarmonyOS开发中列表(List)组件的全面解析
·
本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
HarmonyOS中的List组件是展示结构化、可滚动数据的重要容器,广泛应用于商品列表、联系人、消息记录等场景。本文将全面介绍List组件的使用,包括基础创建、常用API、布局控制、数据绑定、性能优化等核心内容。
一、List组件基础与创建
1. List组件基本概念
List是HarmonyOS中用于显示同类数据集合的滚动容器,具有以下特点:
- 自动提供滚动功能,适合呈现大量数据
- 支持垂直和水平两种滚动方向
- 支持条件渲染、循环渲染和懒加载等优化手段
- 每个列表项(ListItem)只能包含一个根组件
2. 基础List创建示例
// 最简单的静态列表创建
@Entry
@Component
struct BasicList {
build() {
List() {
ListItem() {
Text("列表项1").fontSize(20)
}
ListItem() {
Text("列表项2").fontSize(20)
}
ListItem() {
Text("列表项3").fontSize(20)
}
}
.width('100%')
.height('100%')
}
}
3. 动态数据绑定
实际开发中,我们通常使用ForEach动态绑定数据:
class Item {
key: string;
name: string;
icon: Resource;
constructor(name: string, icon: Resource) {
this.key = util.generateRandomUUID(true); // 生成唯一key
this.name = name;
this.icon = icon;
}
}
@Entry
@Component
struct DynamicList {
private items = [
new Item('商品1', $r("app.media.icon1")),
new Item('商品2', $r("app.media.icon2")),
new Item('商品3', $r("app.media.icon3"))
]
build() {
List() {
ForEach(this.items, (item: Item) => {
ListItem() {
Row() {
Image(item.icon)
.width(40)
.height(40)
.margin(10)
Text(item.name).fontSize(20)
}
.width('100%')
}
}, item => item.key) // 必须提供key生成函数
}
.width('100%')
.height('100%')
}
}
关键点说明:
- 必须为ForEach提供key生成函数,用于唯一标识列表项
- ListItem内部只能有一个根组件,多个组件需要包裹在Row/Column等容器中
- 使用Resource($r)引用应用资源
二、List布局与样式控制
1. 滚动方向设置
List默认是垂直滚动,可通过listDirection属性修改:
List() {
// 列表项
}
.listDirection(Axis.Horizontal) // 设置为水平滚动
2. 多列/多行布局
通过lanes属性实现多列(垂直列表)或多行(水平列表)布局:
// 固定列数
List() {
// 列表项
}
.lanes(2) // 两列布局
// 自适应列宽
List() {
// 列表项
}
.lanes({ minLength: 200, maxLength: 300 }) // 根据宽度自适应
3. 列表项对齐方式
使用alignListItem控制列表项在交叉轴方向的对齐:
List() {
// 列表项
}
.alignListItem(ListItemAlign.Center) // 居中对齐
4. 间距与分隔线
// 设置列表项间距
List({ space: 10 }) { // 主轴方向间距10vp
// 列表项
}
// 添加分隔线
List() {
// 列表项
}
.divider({
strokeWidth: 2, // 线宽
color: Color.Red, // 颜色
startMargin: 20, // 起始边距
endMargin: 20 // 结束边距
})
5. 内容边距控制
List() {
// 列表项
}
.contentStartOffset(50) // 顶部内容边距
.contentEndOffset(50) // 底部内容边距
三、List常用API与高级功能
1. 滚动控制API
List({ initialIndex: 3 }) { // 初始定位到第4个项
// 列表项
}
.onScrollIndex((start: number, end: number, center: number) => {
// 滚动位置变化回调
console.log(`可见项: ${start}到${end}, 中心项: ${center}`);
})
.chainAnimation(true) // 启用链式联动效果
2. 性能优化API
List() {
// 列表项
}
.cachedCount(5) // 预加载项数
.edgeEffect(EdgeEffect.Spring) // 边缘弹性效果
3. 列表项大小控制
当列表项大小不一致时,需要额外指定:
// 创建大小控制器
childrenMainSize: ChildrenMainSize = new ChildrenMainSize(100)
aboutToAppear() {
// 设置特定位置项的大小
this.childrenMainSize.splice(3, 4, [200, 200, 200, 200])
this.childrenMainSize.update(9, 200)
}
build() {
List() {
// 列表项
}
.childrenMainSize(this.childrenMainSize) // 应用大小控制
}
4. 复合列表项(ComposeListItem)
HarmonyOS提供了内置的复合列表项组件:
List({ space: 10 }) {
ComposeListItem({
contentItem: {
iconStyle: IconType.HEAD_SCULPTURE,
icon: $r('app.media.app_icon'),
primaryText: '主标题',
secondaryText: '副标题',
description: '描述文本'
},
operateItem: {
switch: { isCheck: true, onChange: (value) => {} }
}
})
// 更多复合项
}
5. 嵌套水平滚动列表
在垂直列表中嵌套水平滚动的子列表,实现类似电商分类页面的效果:
@Entry
@Component
struct NestedList {
private horizontalItems = [
{ name: '推荐', id: '1' },
{ name: '热门', id: '2' }
]
build() {
List() {
ForEach(this.horizontalItems, (item) => {
ListItem() {
List({ scroller: new Scroller(), listDirection: Axis.Horizontal }) {
ForEach([1, 2, 3, 4], (subItem) => {
ListItem() {
Text(`子项${subItem}`)
.padding(10)
.backgroundColor('#f0f0f0')
}
})
}
.height(100)
.divider({ strokeWidth: 0 }) // 隐藏分割线
}
})
}
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST, // 父列表优先滚动
scrollBackward: NestedScrollMode.SELF_FIRST // 子列表优先回弹
})
}
}
关键点:
- 通过
nestedScroll配置父子列表的滚动优先级 - 水平列表需设置
listDirection: Axis.Horizontal
四、List数据操作与交互
1. 商品列表示例
class Product {
name: string
image: Resource
price: number
discount: number
constructor(name: string, image: Resource, price: number, discount = 0) {
this.name = name
this.image = image
this.price = price
this.discount = discount
}
}
@Entry
@Component
struct ProductList {
private products = [
new Product('Mate60', $r('app.media.a'), 6999, 500),
new Product('小米', $r('app.media.b'), 4999),
new Product('OPPO', $r('app.media.c'), 2000)
]
build() {
List({space: 8}) {
ForEach(this.products, (item: Product) => {
ListItem() {
Row() {
Image(item.image).width(100).height(100)
Column({space: 4}) {
if (item.discount) {
Text(item.name).fontSize(20).fontWeight(FontWeight.Bold)
Text(`原价¥${item.price}`)
.fontSize(14)
.fontColor('#ccc')
.decoration({type: TextDecorationType.LineThrough})
Text(`折扣价¥${item.price - item.discount}`)
.fontSize(20)
.fontColor('#f36')
} else {
Text(item.name).fontSize(20).fontWeight(FontWeight.Bold)
Text(`¥${item.price}`).fontSize(18).fontColor('#f36')
}
}
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.backgroundColor('#FFF')
.borderRadius(20)
.height(120)
.padding(10)
.onClick(() => {
// 点击事件处理
})
}
})
}
.width('100%')
.height('100%')
}
}
关键特性:
- 支持条件渲染(if/else)显示不同价格信息
- 丰富的样式控制(圆角、背景色、内边距等)
- 点击事件处理
2. 分组列表
使用ListItemGroup实现分组:
class Group {
title: string
items: Item[]
constructor(title: string, items: Item[]) {
this.title = title
this.items = items
}
}
@Entry
@Component
struct GroupList {
private groups = [
new Group('A组', [new Item('A1', $r('app.media.a1')), ...]),
new Group('B组', [new Item('B1', $r('app.media.b1')), ...])
]
build() {
List() {
ForEach(this.groups, (group: Group) => {
ListItemGroup() {
// 组标题
ListItem() {
Text(group.title).fontSize(24).fontWeight(FontWeight.Bold)
}
// 组内项
ForEach(group.items, (item: Item) => {
ListItem() {
// 项内容
}
})
}
})
}
}
}
3. 侧滑操作(SwipeAction)
为列表项添加左滑/右滑操作菜单(如删除、收藏):
@Builder
swipeEndBuilder() {
Button('删除')
.width(80)
.height('100%')
.backgroundColor(Color.Red)
.onClick(() => { /* 删除逻辑 */ })
}
List() {
ForEach(this.items, (item) => {
ListItem() {
Text(item.name)
}
.swipeAction({ end: this.swipeEndBuilder }) // 右滑触发
})
}
注意:
swipeAction的Builder中只能包含单个组件- 可通过
edgeEffect配置滑动阻尼效果
4. 拖拽排序 启用列表项拖拽重新排序(需API 7+):
List() {
ForEach(this.items, (item) => {
ListItem() {
Text(item.name)
}
.editable(true) // 启用编辑模式
})
}
.editMode(true) // 开启列表编辑
.onItemMove((from, to) => { /* 更新数据顺序 */ })
五、总结
1. 性能优化策略
-
合理使用key:ForEach必须提供稳定唯一的key,避免使用索引作为key
-
控制渲染范围:
List() {
// ...
}
.cachedCount(5) // 预渲染项数
3. 避免复杂计算:在build函数中避免复杂计算,提前处理数据
4.使用懒加载:对于复杂列表项,使用LazyForEach替代ForEach
2. 常见问题解决
-
内存泄漏检测:
- 使用DevEco Studio的内存分析工具
- 检查事件监听器的注销
-
列表滚动卡顿:
- 优化列表项布局复杂度
- 减少不必要的透明度动画
- 使用willChange提示浏览器优化
更多推荐

所有评论(0)