写点什么

Sections 多列混排

作者:狼哥
  • 2025-03-19
    广东
  • 本文字数:2598 字

    阅读完需:约 9 分钟

Sections 多列混排

学习点

  • @Reusable 装饰器

  • WaterFlow 瀑布流容器

  • 模块组件

  • 代码讲解

效果图

https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtybbs/074/332/081/0260086000074332081.20250309012540.99471717768932048567801652877818:50001231000000:2800:C6C449A57DACAC5F2E175537BB3968AFFF297532F9009E33B47AB7C2C3AFCADA.gif

@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)      }
复制代码


@Reusable@Componentstruct ReusableFlowItem {  @State item: Record<string, Object> = {};  public imgPath: string = ''
aboutToReuse(params: Record<string, Object>) { this.item = params.item as Record<string, Object>; }}
复制代码

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 文件,导出模块组件,提供给外部使用

代码讲解

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

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

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

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

import { SectionsComponent } from 'sectionslibrary';
复制代码


    Column() {      SectionsComponent({imgPath: this.imgPath, dataArray: this.dataArray})    }
复制代码

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);    })  }}
复制代码

6. SectionsComponent 组件讲解

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

  2. 导出 WaterFlow 组件

总结

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


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




发布于: 刚刚阅读数: 6
用户头像

狼哥

关注

还未添加个人签名 2024-10-18 加入

还未添加个人简介

评论

发布
暂无评论
Sections 多列混排_HarmonyOS NEXT_狼哥_InfoQ写作社区