渐进式编程课
鸿蒙 目录
第 8 课2026.07.13

时效校验:20260915(HarmonyOS API 20 SDK、华为官方 Navigation 文档)

第 8 课:Navigation 基础页面跳转

  • 日期:2026-07-13
  • 时效校验:2026-09-15(HarmonyOS API 20 SDK、华为官方 Navigation 文档)
  • 知识点:Navigation、NavPathStack、NavDestination
  • 适用场景:点击列表项后进入详情内容

承接上一课的 TopicPage:列表、稳定 key、点击事件和 selectedId 全部保留,这一课只增加“点击后进入详情”这一条能力。

旧的全局 router.pushUrl 从 API 18 起已废弃。新应用课程改用华为当前推荐的 Navigation + NavPathStack,但不会在这一课提前加入参数和返回逻辑。

1. 给上一课的列表加一个导航容器

下面的 TopicItem、topics 和 selectedId 都来自第 7 课。新增的只有 pathStack、Navigation、目标页 Builder,以及点击时的 pushPath()。

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

@Entry
@Component
struct TopicPage {
  pathStack: NavPathStack = new NavPathStack();
  @State topics: Array<TopicItem> = [
    { id: '001', title: 'UIAbility' },
    { id: '002', title: '@State' },
    { id: '003', title: 'List' }
  ];
  @State selectedId: string = '001';

  @Builder
  pageBuilder(name: string) {
    if (name === 'DetailPage') {
      DetailPage()
    }
  }

  build() {
    Navigation(this.pathStack) {
      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;
              this.pathStack.pushPath({ name: 'DetailPage' });
            })
          }
        }, (item: TopicItem) => item.id)
      }
      .width('100%')
      .height('100%')
    }
    .title('主题列表')
    .navDestination(this.pageBuilder)
  }
}

@Component
struct DetailPage {
  build() {
    NavDestination() {
      Text('详情页')
        .fontSize(24)
    }
    .title('详情')
  }
}

2. 先只理解一条链路

text
第 7 课的列表点击
-> pushPath 把 DetailPage 入栈
-> pageBuilder 构建 NavDestination
-> 屏幕显示“详情页”

这一课先不关心点击了哪一项,也不手动返回;这两个增量分别留给第 9、10 课。

3~5 分钟练习

把详情页文字改成“这是主题详情”,然后点击任意列表项,确认都能进入同一个静态详情页。

参考答案

ts
Text('这是主题详情')
  .fontSize(24)

与上一课的联系

第 7 课完成“点中哪一行”;这一课不改原列表数据流,只在同一个点击事件后追加“进入详情”。

官方参考