ArkUI ListItemGroup:分组列表不是多加几个标题那么简单

举报
蓝瘦的蜕变 发表于 2026/08/07 09:25:54 2026/08/07
【摘要】 列表一旦有“上午/下午”“今天/本周”“系统/个人”这类归属关系,就别只往 List 里塞一个普通标题。ListItemGroup 能把标题和组内项目绑定在一起,结构会清楚很多。 这个 Demo 看两种分组感 第一块用 ListItemGroup({ header }) 放进 List,并在 List 上打开 stic

ArkUI ListItemGroup:分组列表不是多加几个标题那么简单

列表一旦有“上午/下午”“今天/本周”“系统/个人”这类归属关系,就别只往 List 里塞一个普通标题。ListItemGroup 能把标题和组内项目绑定在一起,结构会清楚很多。

这个 Demo 看两种分组感

第一块用 ListItemGroup({ header }) 放进 List,并在 List 上打开 sticky(StickyStyle.Header)。这只是基础吸顶感,不展开复杂交互。

第二块把同样的数据用静态卡片展示,重点看“组内紧、组间松”的视觉节奏。

List({ space: 12 }) {
  ListItemGroup({ header: this.morningHeader }) {
    ForEach(this.morningItems, (item: GroupRowItem) => {
      ListItem() {
        this.groupRow(item)
      }
    }, (item: GroupRowItem) => item.title)
  }
}
.sticky(StickyStyle.Header)

分组不是装饰,是边界

分组标题的意义不是“多一行字”,而是让用户知道接下来这一批内容属于哪里。真正的通讯录索引、复杂吸顶、滚动定位,后面可以单独讲;这一篇先把分组结构写稳。

你自己的列表里,哪些内容其实已经天然分组了?通知、订单、设置项、联系人,都很容易用上这个结构。

参考文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-list-and-grid

完整示例代码

文件位置:entry/src/main/ets/pages/arkUI/listLayout/ArkUIListItemGroupDemo.ets

class GroupRowItem {
  title: string = '';
  desc: string = '';
  meta: string = '';

  constructor(title: string, desc: string, meta: string) {
    this.title = title;
    this.desc = desc;
    this.meta = meta;
  }
}

@Entry
@Component
struct ArkUIListItemGroupDemo {
  private morningItems: GroupRowItem[] = [
    new GroupRowItem('站会记录', '把昨天的阻塞点先写清楚', '09:30'),
    new GroupRowItem('接口对齐', '字段名和空值策略不要口头约定', '10:15')
  ];

  private afternoonItems: GroupRowItem[] = [
    new GroupRowItem('页面验收', '先看信息层级,再看视觉细节', '14:00'),
    new GroupRowItem('文档补齐', '把 Demo 的边界写在正文里', '15:40'),
    new GroupRowItem('静态检查', '收尾前确认路由和代码块一致', '17:20')
  ];

  @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
  morningHeader() {
    Text('上午')
      .width('100%')
      .padding({ left: 12, right: 12, top: 8, bottom: 8 })
      .fontSize(14)
      .fontWeight(700)
      .fontColor('#0F766E')
      .backgroundColor('#DCFCE7')
  }

  @Builder
  afternoonHeader() {
    Text('下午')
      .width('100%')
      .padding({ left: 12, right: 12, top: 8, bottom: 8 })
      .fontSize(14)
      .fontWeight(700)
      .fontColor('#7C2D12')
      .backgroundColor('#FFEDD5')
  }

  @Builder
  groupRow(item: GroupRowItem) {
    Row({ space: 10 }) {
      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.meta)
        .fontSize(12)
        .fontColor('#64748B')
    }
    .width('100%')
    .height(64)
    .padding({ left: 12, right: 12, top: 8, bottom: 8 })
    .backgroundColor('#FFFFFF')
  }

  build() {
    Scroll() {
      Column({ space: 18 }) {
        Text('ArkUI ListItemGroup')
          .width('100%')
          .fontSize(24)
          .fontWeight(700)
          .fontColor('#0F172A')

        Text('分组列表不是多加几个标题那么简单')
          .width('100%')
          .fontSize(22)
          .fontWeight(700)
          .fontColor('#111827')

        Text('这一页只看分组列表。ListItemGroup 把一组 ListItem 收在一起,header 可以让用户知道当前列表项属于哪一类。')
          .width('100%')
          .fontSize(14)
          .fontColor('#64748B')
          .lineHeight(22)

        Column({ space: 12 }) {
          this.sectionTitle('header 让分组有了边界', '不要只在列表里插一行标题。用 ListItemGroup 后,组标题和组内项目的关系会更清楚。')

          List({ space: 12 }) {
            ListItemGroup({ header: this.morningHeader }) {
              ForEach(this.morningItems, (item: GroupRowItem) => {
                ListItem() {
                  this.groupRow(item)
                }
              }, (item: GroupRowItem) => item.title)
            }

            ListItemGroup({ header: this.afternoonHeader }) {
              ForEach(this.afternoonItems, (item: GroupRowItem) => {
                ListItem() {
                  this.groupRow(item)
                }
              }, (item: GroupRowItem) => item.title)
            }
          }
          .width('100%')
          .height(330)
          .sticky(StickyStyle.Header)
          .backgroundColor('#F8FAFC')
          .borderRadius(8)
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#EFF6FF')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('组间距要比行间距更明显', '同组项目可以靠得近一点,不同组之间要拉开。用户扫一眼就能分清边界。')

          Column({ space: 14 }) {
            Column({ space: 0 }) {
              this.morningHeader()
              ForEach(this.morningItems, (item: GroupRowItem) => {
                this.groupRow(item)
              }, (item: GroupRowItem) => item.title)
            }
            .clip(true)
            .borderRadius(8)

            Column({ space: 0 }) {
              this.afternoonHeader()
              ForEach(this.afternoonItems, (item: GroupRowItem) => {
                this.groupRow(item)
              }, (item: GroupRowItem) => item.title)
            }
            .clip(true)
            .borderRadius(8)
          }
          .width('100%')
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F0FDF4')
        .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个月内不可修改。