ArkUI List:别再用 Column 硬堆列表了
【摘要】 列表一多,就不要继续用 Column 往下堆了。List 自带滚动能力,子项也有明确边界,后面要做分组、吸顶、横滑或懒加载时,路也更顺。 这个 Demo 先看三件事 第一块是纵向列表。我们给 List 一个固定高度,内容超过后它自己滚动。space 负责列表项之间的距离。 第二块是水平列表。把 listDirectio
ArkUI List:别再用 Column 硬堆列表了
列表一多,就不要继续用 Column 往下堆了。List 自带滚动能力,子项也有明确边界,后面要做分组、吸顶、横滑或懒加载时,路也更顺。
这个 Demo 先看三件事
第一块是纵向列表。我们给 List 一个固定高度,内容超过后它自己滚动。space 负责列表项之间的距离。
第二块是水平列表。把 listDirection 改成 Axis.Horizontal 后,滚动方向就变成横向。横向列表项最好给稳定宽度,不然内容会忽宽忽窄。
第三块是 lanes。如果列表项宽度一致,只是想排成两列,lanes 比自己手写一行两个更直接。
ListItem 是基本规矩
List 的子组件应该是 ListItem 或 ListItemGroup。这不是形式主义,而是为了让列表滚动、复用、分组这些能力有清晰结构。
List({ space: 10 }) {
ForEach(this.tasks, (item: ListDemoItem) => {
ListItem() {
this.taskRow(item)
}
}, (item: ListDemoItem) => item.title)
}
.height(250)
这一篇不讲增删改,也不讲勾选状态刷新。那些属于状态章节。这里我们只把列表容器本身写稳。
你现在项目里有没有还在用 Column + ForEach 硬堆长列表的页面?可以拿这个 Demo 的第一块替换试试,滚动边界会清楚很多。
参考文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-list-and-grid
完整示例代码
文件位置:entry/src/main/ets/pages/arkUI/listLayout/ArkUIListDemo.ets
class ListDemoItem {
title: string = '';
desc: string = '';
tag: string = '';
color: string = '';
constructor(title: string, desc: string, tag: string, color: string) {
this.title = title;
this.desc = desc;
this.tag = tag;
this.color = color;
}
}
@Entry
@Component
struct ArkUIListDemo {
private tasks: ListDemoItem[] = [
new ListDemoItem('整理需求', '把今天要做的事情先列清楚', '09:20', '#2563EB'),
new ListDemoItem('检查设计稿', '确认列表项里哪些信息必须露出', '10:10', '#0F766E'),
new ListDemoItem('写接口说明', '字段含义不清楚时先补注释', '11:40', '#C2410C'),
new ListDemoItem('同步测试结论', '把阻塞点和下一步写在一起', '14:30', '#7C3AED'),
new ListDemoItem('收尾检查', '确认页面滚动边界没有被挤乱', '17:10', '#1D4ED8')
];
private cards: string[] = ['待办', '提醒', '收藏', '最近', '草稿', '归档'];
@Builder
sectionTitle(title: string, desc: string) {
Column({ space: 4 }) {
Text(title)
.width('100%')
.fontSize(16)
.fontWeight(700)
.fontColor('#0F172A')
Text(desc)
.width('100%')
.fontSize(13)
.fontColor('#64748B')
.lineHeight(20)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
}
@Builder
taskRow(item: ListDemoItem) {
Row({ space: 12 }) {
Text(item.title.substring(0, 1))
.width(38)
.height(38)
.fontSize(16)
.fontWeight(700)
.fontColor('#FFFFFF')
.textAlign(TextAlign.Center)
.backgroundColor(item.color)
.borderRadius(8)
Column({ space: 4 }) {
Text(item.title)
.width('100%')
.fontSize(15)
.fontWeight(700)
.fontColor('#0F172A')
Text(item.desc)
.width('100%')
.fontSize(12)
.fontColor('#64748B')
.lineHeight(18)
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
Text(item.tag)
.fontSize(12)
.fontColor('#64748B')
}
.width('100%')
.height(66)
.padding({ left: 12, right: 12, top: 10, bottom: 10 })
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#E2E8F0' })
.borderRadius(8)
}
build() {
Scroll() {
Column({ space: 18 }) {
Text('ArkUI List')
.width('100%')
.fontSize(24)
.fontWeight(700)
.fontColor('#0F172A')
Text('别再用 Column 硬堆列表了')
.width('100%')
.fontSize(22)
.fontWeight(700)
.fontColor('#111827')
Text('这一页只看 List 本体:纵向列表、水平列表、固定高度滚动和 lanes 多列。列表里的数据不做增删改,先把容器边界写稳。')
.width('100%')
.fontSize(14)
.fontColor('#64748B')
.lineHeight(22)
Column({ space: 12 }) {
this.sectionTitle('纵向列表是最常见的起点', 'List 的子组件要用 ListItem。space 控制列表项之间的距离,固定高度让内容超出时自然滚动。')
List({ space: 10 }) {
ForEach(this.tasks, (item: ListDemoItem) => {
ListItem() {
this.taskRow(item)
}
}, (item: ListDemoItem) => item.title)
}
.width('100%')
.height(250)
}
.width('100%')
.padding(16)
.backgroundColor('#EFF6FF')
.borderRadius(8)
Column({ space: 12 }) {
this.sectionTitle('水平列表适合横向入口', '方向一改,滚动轴也跟着变。横向内容最好给列表项一个稳定宽度,不然每项会忽宽忽窄。')
List({ space: 10 }) {
ForEach(this.cards, (item: string, index: number) => {
ListItem() {
Column({ space: 8 }) {
Text(item)
.fontSize(16)
.fontWeight(700)
.fontColor('#0F172A')
Text(`入口 ${index + 1}`)
.fontSize(12)
.fontColor('#64748B')
}
.width(126)
.height(86)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#BBF7D0' })
.borderRadius(8)
}
}, (item: string) => item)
}
.width('100%')
.height(104)
.listDirection(Axis.Horizontal)
}
.width('100%')
.padding(16)
.backgroundColor('#F0FDF4')
.borderRadius(8)
Column({ space: 12 }) {
this.sectionTitle('lanes 可以先做简单多列', '列表项宽度相同、只是想排成两列时,List 的 lanes 比自己手算一行两个更直接。')
List({ space: 10 }) {
ForEach(this.cards, (item: string, index: number) => {
ListItem() {
Text(item)
.width('100%')
.height(58)
.fontSize(15)
.fontWeight(700)
.fontColor(index % 2 === 0 ? '#6D28D9' : '#9A3412')
.textAlign(TextAlign.Center)
.backgroundColor(index % 2 === 0 ? '#F5F3FF' : '#FFF7ED')
.borderRadius(8)
}
}, (item: string) => item)
}
.lanes(2)
.width('100%')
.height(210)
}
.width('100%')
.padding(16)
.backgroundColor('#F8FAFC')
.borderRadius(8)
}
.width('100%')
.padding(20)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)