渐进式编程课
鸿蒙 目录
第 7 课2026.07.10

适用场景:设置选项、学习目录、行情列表选股、搜索结果点击

第 7 课:列表点击与选中状态

  • 日期:2026-07-10
  • 知识点:列表项点击、数据驱动的选中状态
  • 适用场景:设置选项、学习目录、行情列表选股、搜索结果点击

承接上一课的 List/ListItem:列表能展示数据后,下一步通常是处理“用户点了哪一行”。

核心概念

列表项本身不维护脱离数据流的状态。父组件持有一个 selectedId,点击某一行时更新它;UI 根据 selectedId 判断哪一行被选中。

ts
interface TopicItem {
  id: string;
  title: string;
}

@Entry
@Component
struct TopicPage {
  @State topics: TopicItem[] = [
    { id: '001', title: 'UIAbility' },
    { id: '002', title: '@State' },
    { id: '003', title: 'List' }
  ];

  @State selectedId: string = '001';

  build() {
    List({ space: 8 }) {
      ForEach(this.topics, (item: TopicItem) => {
        ListItem() {
          Row() {
            Text(item.title)
              .fontSize(20)
              .layoutWeight(1)

            if (this.selectedId === item.id) {
              Text('已选')
                .fontSize(14)
            }
          }
          .width('100%')
          .padding(16)
          .onClick(() => {
            this.selectedId = item.id;
          })
        }
      }, (item: TopicItem) => item.id)
    }
    .width('100%')
    .height('100%')
  }
}

关键链路:

text
点击 ListItem
-> 更新 selectedId
-> UI 重新判断 selectedId === item.id
-> 对应行显示“已选”

3~5 分钟练习

把默认选中项改成 '003',再新增 { id: '004', title: '点击事件' }。点击不同列表项,观察“已选”是否只出现在当前点击的一行。

参考答案

ts
@State selectedId: string = '003';

// topics 中新增:
{ id: '004', title: '点击事件' }

与上一课的联系

上一课构建了数据列表;这一课给列表补上交互,并继续坚持“状态属于数据源,UI 只根据状态渲染”的原则。