ArkUI List:别再用 Column 硬堆列表了

举报
蓝瘦的蜕变 发表于 2026/08/05 11:52:10 2026/08/05
【摘要】 列表一多,就不要继续用 Column 往下堆了。List 自带滚动能力,子项也有明确边界,后面要做分组、吸顶、横滑或懒加载时,路也更顺。 这个 Demo 先看三件事 第一块是纵向列表。我们给 List 一个固定高度,内容超过后它自己滚动。space 负责列表项之间的距离。 第二块是水平列表。把 listDirectio

ArkUI List:别再用 Column 硬堆列表了

列表一多,就不要继续用 Column 往下堆了。List 自带滚动能力,子项也有明确边界,后面要做分组、吸顶、横滑或懒加载时,路也更顺。

这个 Demo 先看三件事

第一块是纵向列表。我们给 List 一个固定高度,内容超过后它自己滚动。space 负责列表项之间的距离。

第二块是水平列表。把 listDirection 改成 Axis.Horizontal 后,滚动方向就变成横向。横向列表项最好给稳定宽度,不然内容会忽宽忽窄。

第三块是 lanes。如果列表项宽度一致,只是想排成两列,lanes 比自己手写一行两个更直接。

ListItem 是基本规矩

List 的子组件应该是 ListItemListItemGroup。这不是形式主义,而是为了让列表滚动、复用、分组这些能力有清晰结构。

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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。