Sections 多列混排 原创

狼哥Army
发布于 2025-3-12 10:39
浏览
2收藏

学习点

  • @Reusable 装饰器
  • WaterFlow瀑布流容器
  • 模块组件
  • 代码讲解

效果图

Sections 多列混排-鸿蒙开发者社区

@Reusable 装饰器使用场景

@Reusable 是一个在 HarmonyOS ArkTS 中使用的装饰器,主要用于自定义组件的复用。从 API version 10 开始,@Reusable 装饰器得到了支持。它的主要功能是当一个标记为 @Reusable 的自定义组件从组件树上被移除时,该组件及其对应的 JSView 对象会被放入复用缓存中。这样,在后续需要创建新的自定义组件节点时,可以复用缓存区中的节点,从而节约组件重新创建的时间。

  • 列表滚动:当应用需要展示大量数据的列表,并且用户进行滚动操作时,频繁创建和销毁列表项的视图可能导致卡顿和性能问题。在这种情况下,使用列表组件的组件复用机制可以重用已经创建的列表项视图,提高滚动的流畅度。
  • 动态布局更新:如果应用中的界面需要频繁地进行布局更新,例如根据用户的操作或数据变化动态改变视图结构和样式,重复创建和销毁视图可能导致频繁的布局计算,影响帧率。在这种情况下,使用组件复用可以避免不必要的视图创建和布局计算,提高性能。
  • 频繁创建和销毁数据项的视图场景下。使用组件复用可以重用已创建的视图,只更新数据的内容,减少视图的创建和销毁,能有效提高性能。

使用场景和限制条件 @Reusable 装饰器主要用于自定义组件,它只能与 @Component 结合使用。这意味着你可以在自定义组件的定义中使用 @Reusable 来标记那些需要被复用的组件。尝试过@Reusable 装饰器和@ComponentV2结合使用,显示不出来效果,可能目前@Reusable 装饰器目前还不支持@ComponentV2结合使用。

WaterFlow使用场景

​ WaterFlow滑动场景存在FlowItem及其子组件的频繁创建和销毁,可以将FlowItem中的组件封装成自定义组件,并使用@Reusable装饰器修饰,使其具备组件复用能力。

 WaterFlow({ scroller: this.scroller, sections: this.sections }) {
        LazyForEach(this.dataSource, (item: Record<string, Object>) => {
          FlowItem() {
            ReusableFlowItem({ item: item, imgPath: this.imgPath })
          }
        }, (item: string) => item)
      }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
@Reusable
@Component
struct ReusableFlowItem {
  @State item: Record<string, Object> = {};
  public imgPath: string = ''

  aboutToReuse(params: Record<string, Object>) {
    this.item = params.item as Record<string, Object>;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

SectionsComponent模块组件实现

  1. 右击项目名称 -> 新建 -> 模块 -> Static Library -> Module name: SectionsComponent

  2. 右击SectionsComponent模块ets目录 -> 新建 -> 目录 -> components

  3. 创建SectionsComponent组件,并export导出

  4. 右击SectionsComponent模块ets目录 -> 新建 -> 目录 -> model

  5. 创建WaterFlowDataSource类,实现IDataSource接口,并export导出

  6. 在SectionsComponent模块根目录下Index.ets文件,导出模块组件,提供给外部使用

    export { SectionsComponent } from './src/main/ets/components/SectionsComponent';
    
    • 1.

代码讲解

1. 下图就是模块组件的代码结构图

Sections 多列混排-鸿蒙开发者社区

2. 注意模块组件里oh-package.json5文件里的name

Sections 多列混排-鸿蒙开发者社区

3. 在entry模块下oh-package.json5引用模块组件

Sections 多列混排-鸿蒙开发者社区

4. 在Index.ets主界面引用模块组件

import { SectionsComponent } from 'sectionslibrary';
  • 1.
    Column() {
      SectionsComponent({imgPath: this.imgPath, dataArray: this.dataArray})
    }
  • 1.
  • 2.
  • 3.

5. WaterFlowDataSource数据源类讲解

export class WaterFlowDataSource implements IDataSource {
  private dataArray: Record<string, Object>[] = []
  private listeners: DataChangeListener[] = []
  /**
   * 构造函数
   * @param dataArray
   */
  constructor(dataArray: Record<string, Object>[]) {
    this.dataArray = dataArray
  }
  /**
   * 获得数据总数
   * @returns
   */
  totalCount(): number {
    return this.dataArray.length;
  }
  /**
   * 获取索引值index对应的数据
   * @param index
   * @returns
   */
  getData(index: number): Record<string, Object> {
    return this.dataArray[index];
  }
  /**
   * 注册数据改变的监听器
   * @param listener
   */
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      this.listeners.push(listener)
    }
  }
  /**
   * 注销数据改变的监听器
   * @param listener
   */
  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      this.listeners.splice(pos, 1);
    }
  }
  /**
   * 追加数据
   */
  public addLastItem(): void {
    // start:指定修改开始的位置(索引)。
    // deleteCount(可选):一个整数,表示要移除的数组元素的个数。如果省略,则移除从start位置到数组末尾的所有元素。
    // ...items(可选):要添加进数组的新元素,从start位置开始。如果没有指定,则只删除元素。
    // 在索引数组长度的位置插入当前数组长度,不删除任何元素。
    let obj: Record<string, Object> = { 'key': this.dataArray.length, 'value': `${(this.dataArray.length) % 4}.png` }
    this.dataArray.splice(this.dataArray.length, 0, obj );
    this.notifyDataAdd(this.dataArray.length - 1);
  }
  // 通知数据有添加
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
    })
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.

6. SectionsComponent组件讲解

  1. 使用@Reusable 装饰器标记被复用的组件

    @Reusable
    @Component
    struct ReusableFlowItem {
      @State item: Record<string, Object> = {};
      public imgPath: string = ''
    
      aboutToReuse(params: Record<string, Object>) {
        this.item = params.item as Record<string, Object>;
      }
    
      build() {
        ...
      }
    }
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
    • 11.
    • 12.
    • 13.
    • 14.
  2. 导出WaterFlow组件

    @Component
    export struct SectionsComponent {
      public imgPath: string = '';
      @Link dataArray: Record<string, Object>[];
    
      build() {
        Column({ space: 0 }) {
          WaterFlow({ scroller: this.scroller, sections: this.sections }) {
            LazyForEach(this.dataSource, (item: Record<string, Object>) => {
              FlowItem() {
                ReusableFlowItem({ item: item, imgPath: this.imgPath })
              }
            }, (item: string) => item)
          }
        }
      }
    }
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
    • 11.
    • 12.
    • 13.
    • 14.
    • 15.
    • 16.
    • 17.

总结

​ 通过使用@Reusable 装饰器标记复用组件,结合LazyForEach懒加载,丝滑感觉就出来了,想尝试这丝滑感觉的,可以在源码仓库或附件里下载源代码体验一下,本项目创建时选择的API13,可以通过本地模拟器上运行体验,开发这个Sample时,使用的开发工具是DevEco Studio 5.0.3 Beta2,里面集成了DeepSeek,大家也可以下载最新版本体验一下。

源码仓库:https://atomgit.com/next_project/SectionsWaterFlowSample

Sections 多列混排-鸿蒙开发者社区

Sections 多列混排-鸿蒙开发者社区

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
SectionsWaterFlowSample-master.zip 11.76M 0次下载
1
收藏 2
回复
举报
1
2
2
2条回复
按时间正序
/
按时间倒序
鸿蒙活动小助手
鸿蒙活动小助手

超赞的帖子!大家来学习!

回复
2025-3-13 16:40:46
辣条条2025
辣条条2025 回复了 鸿蒙活动小助手
超赞的帖子!大家来学习!

学习一下。

回复
2025-3-16 16:48:02


回复
    相关推荐