Sections 多列混排

news/2025/3/15 11:44:18/文章来源:https://www.cnblogs.com/army16/p/18773437

学习点

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

效果图

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

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

代码讲解

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 装饰器标记被复用的组件

    @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() {...}
    }
    
  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)}}}
    }
    

总结

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/899104.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

后缀数组(SA)学习笔记(倍增算法)

倍增求SA后缀数组是一个非常好的东西。一开始看不出来这个东西有什么用,但是它非常的有用。(以下 \(N\) 为字符串长度) 有了后缀数组,我们就可以在 \(O(N \log N)\) 的时间内:得到所有后缀的字典序关系。(最基本的功能) 求出任意两个子串的最长公共前缀 (LCP)。 求出字符…

Chat2DB 数据库客户端邀请码

推荐一款超好用的AI数据库管理工具Chat2DB,支持22种数据库,包括国产的达梦、OpenGuass、OceanBase、TiDB等,还有非关系型MongoDB、Redis等,快来试试吧! 🔥 官网:https://chat2db-ai.com/ 🔥 邀请码:622888 邀请码介绍:https://docs.chat2db-ai.com/docs/settings/i…

基于Java的全栈入门学习路线

Java全栈JavaSE数据库前端JavaWebSSM框架Linux学完以上可独立开发,下面是微服务协同开发 SpringBootSpringCloudHadoop

latex中如何重复引用已经存在的脚注?

在使用latex写论文的时候,如果要添加一个脚注,可以使用 \footnote{...}如果第二次出现相同内容的脚注,再写一次\footnote{...}会导致出现两个脚注,我们希望两处脚注链接到一处,可以这样写: 第一处脚注添加label: \footnote{...\label{llama3.2}}第二处及之后的脚注直接引…

编译libssh (Windows VS)

1、先编译依赖的zlib 下载地址 zlib Home Site 解压后,文件夹处——鼠标右键——VS Code打开,选择vs编译器,开始自动编译得到build目录 以管理员身份运行VS,打开build目录里的zlib.sln,我需要的是64位的,所以选择如下 ALL_BUILD处生成lib和dll,然后INSTALL处也生成下(自…

【学习笔记】wqs二分

其实写这个主要是想解释一下它的原理,教程、习题什么的网上都有,比如这个。 就拿这题来讲吧。 首先我们画出一个函数 \(f(x)\) 表示 \(s\) 的度恰好为 \(x\) 时,最小生成树的权值和。 当然,这个函数只会取在某一些整点上,我们把它连起来就行了。 然后你会发现它是下凸的(…

在vue2中引用高德地图,外卖骑手的路线规划

参照路径规划-参考手册-地图 JS API 1.4 | 高德地图APIAMap.RidingAMap.Riding骑行路径规划服务,提供起始、终点骑行路线查询服务。用户可以通过自定义回调函数取回并显示查询结果。若服务请求失败,系统将返回错误信息。 相关示例:位置经纬度 + 骑行路线规划-骑行路径规划-示…

软件分析——OBS Studio

课程社区链接:首页 - 2025年春季软件工程(罗杰、任健) - 北京航空航天大学 - 班级博客 - 博客园 (cnblogs.com) 作业要求链接:[I.2] 个人作业:软件案例分析 - 作业 - 2025年春季软件工程(罗杰、任健) - 班级博客 - 博客园 (cnblogs.com) 课程目标:让学生掌握软件开发的…

JDK7-时间类、时间格式化类--java进阶day07

1.Date类:表示时间的类 1.Date常用的构造方法.2.Date常用的成员方法1.getTime:返回从时间原点到对象设定的时间之间的时间2.setTime:将对象的时间设置为setTime里的时间 d3是此刻的时间,被setTime设置为了时间原点2.SimpleDateFormat类:时间格式化类 Date类默认的格式不好看…

RN里遇到初始计算值是一样的,布局位置却不一致的问题

在tabs切换下面的小动画 但在页面上显示确是这样的,只有切换回来一次后才显示正常。计算结果确始终都是7 问了下AI,说是,在RN中,布局计算是异步的。在组件首次渲染时,即使布局事件已经触发并且获取到了layout对象,实际DOM可能还没有完全应用这些尺寸。这会导致第一次动画…

idea安装激活图文详细教程_激活至永久_亲测有效

一、安装 IDEA打开下载好的安装包,按照提示完成安装。 image.png自定义安装路径,我这里安装在了 E:\ 盘下,继续点击下一步按钮: image.png image.png安装完成后,暂时不要启动程序,直接关闭它。三、补丁安装步骤 1. 下载补丁 点击以下链接获取补丁:点击获取补丁文件。htt…

『Plotly实战指南』--绘图初体验

今天,打算通过绘制一个简单的散点图,来开启我们 Plotly 绘图的初次尝试。 本文目的不是介绍如何绘制散点图,而是通过散点图来介绍Plotly 绘图的基础步骤。 1. 绘制散点图:初探 Plotly 散点图是展示变量关系的基础图表,在Plotly中,绘制散点图非常简单。 以下是一个示例代码…