03-万少带你精读鸿蒙codelabs——基于List组件实现二级联动效果 原创 精华

万少skr
发布于 2025-7-18 15:13
浏览
0收藏

03-万少带你精读鸿蒙codelabs——基于List组件实现二级联动效果

原文链接 https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_NEXT-SecondLevelLinkage

1. 功能介绍

本案例实现了一个课程分类展示系统,主要包含以下核心功能:

  • 双栏联动布局(左侧分类导航栏+右侧课程列表)
  • 分类切换时自动滚动到对应课程区域
  • 滚动课程列表时自动同步分类选中状态
  • 加载状态管理(显示Loading提示)
  • 自适应屏幕布局

03-万少带你精读鸿蒙codelabs——基于List组件实现二级联动效果-鸿蒙开发者社区

2. 关键组件

组件/装饰器 作用说明
List 构建可滚动列表容器(左侧分类列表和右侧课程列表)
ForEach 循环渲染分类和课程条目
@State 管理组件状态(当前选中分类、数据加载状态)
@Builder 构建可复用的UI片段(列表分组头部)
Scroller 控制列表滚动行为
ListItemGroup 创建带分组的列表项
StickyStyle.Header 实现分组头部粘滞效果

3. 逻辑思路

主要交互流程说明:

  1. 初始化阶段:通过setTimeout模拟异步数据加载,设置500ms延迟(实际开发中应替换为真实API调用)
  2. 布局渲染:使用Row容器嵌套两个List实现双栏布局,左侧固定宽度,右侧自适应剩余空间
  3. 分类联动
    • 点击左侧分类时,通过scrollToIndex控制右侧列表滚动
    • 滚动右侧列表时,通过onScrollIndex监听首项索引,反向控制左侧分类选中状态
  4. 性能优化
    • 使用sticky属性实现分组头部粘滞
    • 设置scrollBar(BarState.Off)隐藏滚动条
    • 通过edgeEffect(EdgeEffect.None)禁用边缘发光效果

示例图

03-万少带你精读鸿蒙codelabs——基于List组件实现二级联动效果-鸿蒙开发者社区

初始化阶段

初始化阶段:通过setTimeout模拟异步数据加载,设置500ms延迟(实际开发中应替换为真实API调用)

  • currentClassify:当前选中的分类索引。
  • requestSuccess:数据加载是否成功的状态标志。
  • classifyList:分类数据列表。
  • classifyScrollerscroller:用于控制分类列表和课程列表的滚动。
@State currentClassify: number = 0; // selected classify index.
@State requestSuccess: boolean = false; // is loading data.
private classifyList: Array<ClassifyModel> = [];
private classifyScroller: Scroller = new Scroller();
private scroller: Scroller = new Scroller();

  aboutToAppear() {
    // loading data.
    setTimeout(() => {
      this.classifyList = ClassifyViewModel.getLinkData();
      this.requestSuccess = true;
    }, Constants.LOADING_DURATION);
  }

布局渲染

  • build方法用于构建页面的UI布局。
  • 当数据加载成功时,使用List组件渲染分类列表和课程列表。
  • classifyList用于渲染分类列表,每个分类项使用ClassifyItem组件展示。
  • classifyList中的每个分类项包含多个课程项,使用ListItemGroup组件按分类分组展示。
  • 当数据加载失败时,显示一个加载中的提示文本。
build() {
    Row() {
      if (this.requestSuccess) {
        List({ scroller: this.classifyScroller }) {
          ForEach(this.classifyList, (item: ClassifyModel, index?: number) => {
            ListItem() {
              ClassifyItem({
                classifyName: item.classifyName,
                isSelected: this.currentClassify === index,
                onClickAction: () => {
                  if (index !== undefined) {
                    this.classifyChangeAction(index, true);
                  }
                }
              })
            }
          }, (item: ClassifyModel) => item.classifyName.toString() + this.currentClassify)
        }
        .height(Constants.FULL_PERCENT)
        .width($r('app.float.classify_item_width'))
        .backgroundColor($r('app.color.classify_background'))
        .scrollBar(BarState.Off)

        List({ scroller: this.scroller }) {
          ForEach(this.classifyList, (classifyItem: ClassifyModel) => {
            ListItemGroup({
              header: this.ClassifyHeader(classifyItem.classifyName),
              space: Constants.COURSE_ITEM_PADDING
            }) {
              ForEach(classifyItem.courseList, (courseItem: CourseModel) => {
                ListItem() {
                  CourseItem({ itemStr: JSON.stringify(courseItem) })
                }
              }, (courseItem: CourseModel) => `${courseItem.courseId}`)
            }
          }, (item: ClassifyModel) => `${item.classifyId}`)
        }
        .height(Constants.FULL_PERCENT)
        .width(Constants.FULL_PERCENT)
        .padding({ left: $r('app.float.item_padding_left'), right: $r('app.float.course_item_padding') })
        .sticky(StickyStyle.Header)
        .layoutWeight(1)
        .edgeEffect(EdgeEffect.None)
        .onScrollIndex((start: number) => this.classifyChangeAction(start, false))
      } else {
        Text($r('app.string.loading'))
          .fontFamily($r('app.string.hei_ti_medium'))
          .textAlign(TextAlign.Center)
          .height(Constants.FULL_PERCENT)
          .width(Constants.FULL_PERCENT)
      }
    }
    .backgroundColor($r('app.color.base_background'))
  }

分类联动

  • 点击左侧分类时,通过scrollToIndex控制右侧列表滚动

03-万少带你精读鸿蒙codelabs——基于List组件实现二级联动效果-鸿蒙开发者社区

  • 滚动右侧列表时,通过onScrollIndex监听首项索引,反向控制左侧分类选中状态

03-万少带你精读鸿蒙codelabs——基于List组件实现二级联动效果-鸿蒙开发者社区

性能优化

  • 使用sticky属性实现分组头部粘滞
  • 设置scrollBar(BarState.Off)隐藏滚动条
  • 通过edgeEffect(EdgeEffect.None)禁用边缘发光效果

总结

如果你兴趣想要了解更多的开发细节和最新资讯,欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
标签
1
收藏
回复
举报
回复
    相关推荐