前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >鸿蒙开发实战案例:全局自定义组件复用实现案例思路

鸿蒙开发实战案例:全局自定义组件复用实现案例思路

原创
作者头像
小帅聊鸿蒙
发布2025-02-20 20:47:38
发布2025-02-20 20:47:38
550
举报
文章被收录于专栏:鸿蒙开发笔记鸿蒙开发笔记

介绍

本示例是全局自定义组件复用实现的示例代码,主要讲解如何通过BuilderNode创建全局的自定义组件复用池,实现跨页面的组件复用。

效果图预览

使用说明

  1. 继承NodeController,实现可复用的NodeItem组件。
  2. 使用单例模式创建NodePool组件复用池,根据传入的type类型查找复用池中是否存在可复用的组件,如果有则直接使用,如果没有则重新创建。
  3. 使用NodeContainer组件占位,从复用池NodePool中获取组件加载到页面中。

实现思路

  1. 使用List+Swiper实现Tabs页面切换,详细代码请参考BuilderNodePoolDemo.ets。
代码语言:typescript
复制
     ...
     Swiper(this.swiperController) {
       LazyForEach(this.array, () => {
         TabNode()
       }, (title: string) => title)
     }
     ...
  1. 继承NodeController,实现makeNode,用于组件的创建或刷新,并在组件隐藏时(aboutToDisappear)回收组件,详细代码请参考BuilderNodePool.ets中的NodeItem实现。
代码语言:typescript
复制
   export class NodeItem extends NodeController {
     private callback: UpdaterCallback | null = null;
     ...
     // 父类方法,用于创建子组件
     makeNode(uiContext: UIContext): FrameNode | null {
       if (!this.node) {
         this.node = new BuilderNode(uiContext);
         this.node.build(this.builder, this.data);
       } else {
         this.node.update(this.data);
         this.update(this.data);
       }
       return this.node.getFrameNode();
     }
     // 组件隐藏时回收组件
     aboutToDisappear(): void {
       NodePool.getInstance().recycleNode(this.type, this);
     }
     ...
   }
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
代码语言:erlang
复制
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
  1. 使用单例模式实现复用池,应用内统一管理组件复用。添加getNode方法,根据传入的type参数,获取对应的Node组件,如果未找到,则重新创建,实现recycleNode方法,回收Node组件,详细代码请参考BuilderNodePool.ets中的NodePool实现。
代码语言:typescript
复制
   ...
   export class NodePool {
     private static instance: NodePool;
     ...
   
     private constructor() {
       this.nodePool = new HashMap();
       this.nodeHook = new HashSet();
       this.idGen = 0;
     }
     // 单例模式,可以全局统一管理
     public static getInstance() {
       if (!NodePool.instance) {
         NodePool.instance = new NodePool();
       }
       return NodePool.instance;
     }
     ...
     public getNode(type: string, data: ESObject, builder: WrappedBuilder<ESObject>): NodeItem | undefined {
       let node: NodeItem | undefined = this.nodePool.get(type)?.pop();
       if (!node) {
         node = new NodeItem(builder, data, type);
         this.nodeHook.add(node);
       } else {
         node.data = data;
       }
       node.data.callback = (callback: UpdaterCallback) => {
         if (node) {
           node.registerUpdater(callback);
         }
       }
       return node;
     }
     // 回收Node组件,提供给下次复用
     public recycleNode(type: string, node: NodeItem) {
       let nodeArray: Array<NodeItem> = this.nodePool.get(type);
       if (!nodeArray) {
         nodeArray = new Array();
         this.nodePool.set(type, nodeArray);
       }
       nodeArray.push(node);
     }
   }
   ...
  1. 使用NodeContainer占位轮播图组件和瀑布流子组件的位置,并通过NodePool获取组件加载到页面中,详细代码请参考TabNode.ets。
代码语言:typescript
复制
   ...
   FlowItem() {
     NodeContainer(NodePool.getInstance().getNode('reuse_type_', {
       item: item,
       itemHeight: this.itemHeightArray[index % 100],
       itemColor: this.colors[index % 5],
       updater: (item: ViewItem) => {
         this.fillNewData(item);
       },
       callback: null
     }, flowItemWrapper))
   }
   ...

高性能知识点

通过BuilderNode实现全局自定义组件复用池,解决常规复用中只能在父组件中复用的问题,实现组件的跨父组件、跨页面复用,减少页面的创建耗时,优化应用性能。

工程结构&模块类型

代码语言:shell
复制
   customreusablepool                                 // har类型
   |---constants                                      // 常量
   |---|---Constants.ets                              // 常量类
   |---data                                           // 数据类型
   |---|---MockData.ets                               // 模拟数据
   |---|---TitleBean.ets                              // 标题类
   |---|---TitleDataSource.ets                        // 标题懒加载数据类   
   |---|---ViewItem.ets                               // 瀑布流子组件数据类
   |---|---WaterFlowDataSource.ets                    // 瀑布流子组件懒加载数据类
   |---pages                                          // 页面   
   |---|---BuilderNodePoolDemo.ets                    // 全局自定义组件复用池页面               
   |---utils                                          // 工具类
   |---|---BuilderNodePool.ets                        // 自定义组件复用池
   |---view                                           // 组件   
   |---|---FlowItemNode.ets                           // 自定义组件复用池的瀑布流子组件
   |---|---TabNode.ets                                // 自定义组件复用池的Swiper页面   
   |---|---TitleView.ets                              // 标题View   
   |---|---SwiperView.ets                             // 瀑布流中的轮播图

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力;
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识;
  • 想要获取更多完整鸿蒙最新学习知识点,可关注B站:码牛课堂;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 效果图预览
  • 实现思路
    • DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
  • 高性能知识点
  • 工程结构&模块类型
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档