HarmonyOS NEXT实战开发:使用懒加载开发长列表界面实例

针对List、Grid、WaterFlow、Swiper组件,提供NodeAdapter对象替代ArkTS侧的LazyForEach功能,用于按需生成子组件,其中List组件的属性枚举值为NODE_LIST_NODE_ADAPTER,Grid组件的属性枚举值为NODE_GRID_NODE_ADAPTER,WaterFlow组件的属性枚举值为NODE_WATER_FLOW_NODE_ADAPTER,Swiper组件的属性枚举值为NODE_SWIPER_NODE_ADAPTER。

虽然都用于按需生成组件,但不同于ArkTS的LazyForEach,NodeAdapter对象的规格如下:

  • 设置了NodeAdapter属性的节点,不再支持addChild等直接添加子组件的接口。子组件完全由NodeAdapter管理,使用属性方法设置NodeAdapter时,会判断父组件是否已经存在子节点,如果父组件已经存在子节点,则设置NodeAdapter操作失败,返回错误码。

  • NodeApdater通过相关事件通知开发者按需生成组件,类似组件事件机制,开发者使用NodeAdapter时要注册事件监听器,在监听器事件中处理逻辑,相关事件通过ArkUI_NodeAdapterEventType定义。另外NodeAdapter不会主动释放不在屏幕内显示的组件对象,开发者需要在NODE_ADAPTER_EVENT_ON_REMOVE_NODE_FROM_ADAPTER事件中进行组件对象的释放,或者进行缓存复用。下图展示了典型列表滑动场景下的事件触发机制:

以下示例代码针对接入ArkTS页面章节代码进行优化,引入懒加载机制实现文本列表:

  1. 接入ArkTS,参考接入ArkTS页面

  2. 懒加载适配器相关功能实现。

    // ArkUIListItemAdapter
    // 用于文本列表懒加载功能代码。
    
    #ifndef MYAPPLICATION_ARKUILISTITEMADAPTER_H
    #define MYAPPLICATION_ARKUILISTITEMADAPTER_H
    
    #include <arkui/native_node.h>
    #include <stack>
    #include <string>
    #include <unordered_set>
    
    #include "ArkUIListItemNode.h"
    #include "ArkUITextNode.h"
    #include "nativeModule.h"
    
    namespace NativeModule {
    
    class ArkUIListItemAdapter {
    public:
        ArkUIListItemAdapter()
            : module_(NativeModuleInstance::GetInstance()->GetNativeNodeAPI()), handle_(OH_ArkUI_NodeAdapter_Create()) { // 使用NodeAdapter创建函数。
            // 初始化懒加载数据。
            for (int32_t i = 0; i < 1000; i++) {
                data_.emplace_back(std::to_string(i));
            }
            // 设置懒加载数据。
            OH_ArkUI_NodeAdapter_SetTotalNodeCount(handle_, data_.size());
            // 设置懒加载回调事件。
            OH_ArkUI_NodeAdapter_RegisterEventReceiver(handle_, this, OnStaticAdapterEvent);
        }
    
        ~ArkUIListItemAdapter() {
            // 释放创建的组件。
            while (!cachedItems_.empty()) {
                cachedItems_.pop();
            }
            items_.clear();
            // 释放Adapter相关资源。
            OH_ArkUI_NodeAdapter_UnregisterEventReceiver(handle_);
            OH_ArkUI_NodeAdapter_Dispose(handle_);
        }
    
        ArkUI_NodeAdapterHandle GetHandle() const { return handle_; }
    
        void RemoveItem(int32_t index) {
            // 删除第index个数据。
            data_.erase(data_.begin() + index);
            // 如果index会导致可视区域元素发生可见性变化,则会回调NODE_ADAPTER_EVENT_ON_REMOVE_NODE_FROM_ADAPTER事件删除元素,
            // 根据是否有新增元素回调NODE_ADAPTER_EVENT_ON_GET_NODE_ID和NODE_ADAPTER_EVENT_ON_ADD_NODE_TO_ADAPTER事件。
            OH_ArkUI_NodeAdapter_RemoveItem(handle_, index, 1);
            // 更新新的数量。
            OH_ArkUI_NodeAdapter_SetTotalNodeCount(handle_, data_.size());
        }
    
        void InsertItem(int32_t index, const std::string &value) {
            data_.insert(data_.begin() + index, value);
            // 如果index会导致可视区域元素发生可见性变化,则会回调NODE_ADAPTER_EVENT_ON_GET_NODE_ID和NODE_ADAPTER_EVENT_ON_ADD_NODE_TO_ADAPTER事件,
            // 根据是否有删除元素回调NODE_ADAPTER_EVENT_ON_REMOVE_NODE_FROM_ADAPTER事件。
            OH_ArkUI_NodeAdapter_InsertItem(handle_, index, 1);
            // 更新新的数量。
            OH_ArkUI_NodeAdapter_SetTotalNodeCount(handle_, data_.size());
        }
    
        void MoveItem(int32_t oldIndex, int32_t newIndex) {
            auto temp = data_[oldIndex];
         
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值