HarmonyOS C-API 中 List 组件 adapter 如何使用

HarmonyOS C-API 中 List 组件 adapter 如何使用

HarmonyOS
2024-08-09 16:27:50
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
Heiang
class MyList { 
  public: 
    MyList() 
  { 
  nodeApi_ = ArkUINativeModule::GetInstance()->GetNodeAPI(); 
  // 初始化数据 
  for (int32_t i = 0; i < 1000; i++) { 
  data_.emplace_back(std::to_string(i)); 
} 
adapter_ = OH_ArkUI_NodeAdapter_Create(); 
// 设置节点总数为10000。 
OH_ArkUI_NodeAdapter_SetTotalNodeCount(1000); 
// 设置组件创建、销毁回调。 
adapterCallback_ = new UserCallback(); 
adapterCallback_->callback = [this](void* event) { 
  auto* adapterEvent = reinterpret_cast<ArkUI_NodeAdapterEvent*>(event); 
  auto type = OH_ArkUI_NodeAdapterEvent_GetType(adapterEvent); 
  switch (type) { 
    case NODE_ADAPTER_EVENT_ON_GET_NODE_ID: 
      OnGetChildId(adapterEvent); 
      break; 
    case NODE_ADAPTER_EVENT_ON_CREATE_NODE: 
      OnCreateNewChild(adapterEvent); 
      break; 
    case NODE_ADAPTER_EVENT_ON_DISPOSE_NODE: 
      OnDisposeChild(adapterEvent); 
      break; 
  } 
}; 
OH_ArkUI_NodeAdapter_RegisterEventReceiver(adapter_, adapterCallback_, [](ArkUI_NodeAdapterEvent* event) { 
  auto* userData = reinterpret_cast<UserCallback*>(OH_ArkUI_NodeAdapterEvent_GetUserData(event)); 
  userData->callback(event); 
}); 
// 创建List并设置Adapter和缓存数量。 
list_ = nodeApi_->createNode(ARKUI_NODE_LIST); 
ArkUI_AttributeItem item { nullptr, 0, nullptr, adapter_ }; 
nodeApi_->setAttribute(list_, NODE_LIST_NODE_ITEM_ADAPTER, &item); 
ArkUI_NumberValue value[1] = { { .i32 = 10 } }; 
ArkUI_AttributeItem cacheSize { value, 1 }; 
nodeApi_->setAttribute(list_, NODE_LIST_CACHE_COUNT, &cacheSize); 
} 
~MyList() 
{ 
  nodeApi_->disposeNode(list_); 
  // 销毁Adapter中所有组件。 
  ArkUI_NodeHandle* items = nullptr; 
  uint32_t size = 0; 
  OH_ArkUI_NodeAdapter_GetAllItem(adapter_, &items, &size); 
  for (uint32_t i = 0; i < size; i++) { 
  nodeApi_->disposeNode(items[i]); 
} 
  // 销毁adapter 
  OH_ArkUI_NodeAdapter_Dispose(adapter_); 
  // 销毁缓存组件。 
  while (!nodePool_.empty()) { 
    nodeApi_->disposeNode(nodePool_.top()); 
    nodePool_.pop(); 
  } 
  delete adapterCallback_; 
} 
void ChangeData() 
{ 
  // 删除最后一个数据 
  data_.pop_back(); 
  // 由于index从0开始计算,删除的位置为999。 
  // 如果第999个元素保存在NodeAdapter中,那么会将元素删除并回调NODE_ADAPTER_EVENT_ON_DISPOSE_NODE事件通知开发者释放节点资源。 
  // 如果第999个元素不在NodeAdapter中,不会进行任何操作和回调通知。 
  OH_ArkUI_NodeAdapter_NotifyItemRemove(adapter_, data_.size(), 1); 
  // 新增一个数据 
  data_.push_back("new one"); 
  // 由于index从0开始计算,故插入的位置就在999。 
  // 如果第999个元素位于父组件可视区域中进行展示,那么会回调NODE_ADAPTER_EVENT_ON_GET_NODE_ID事件获取组件标识符, 
  // 随后回调NODE_ADAPTER_EVENT_ON_CREATE_NODE创建节点并保持在NodeAdapter中。 
  // 如果第999个元素不在展示范围中,不会进行任何操作和回调通知。 
  OH_ArkUI_NodeAdapter_NotifyItemInsert(adapter_, data_.size(), 1); 
  // 移动位置。 
  auto iter = data_.begin(); 
  data_.push_back(*iter); 
  data_.erase(iter); 
  // 移动位置不会产生回调。 
  OH_ArkUI_NodeAdapter_NotifyItemMove(adapter_, 0, data_.size() - 1); 
  // 重载数据。 
  std::reverse(data_.begin(), data_.end()); 
  // 框架会基于当前可视范围内的所有元素,重新调用NODE_ADAPTER_EVENT_ON_GET_NODE_ID事件获取组件标识符; 
  // 基于新的标识符和老的标识符进行比较,复用标识符相同的元素; 
  // 针对新的标识符调用NODE_ADAPTER_EVENT_ON_CREATE_NODE创建节点并保持在NodeAdapter中; 
  // 针对需要删除的标识符调用NODE_ADAPTER_EVENT_ON_DISPOSE_NODE事件通知开发者释放节点资源。 
  OH_ArkUI_NodeAdapter_NotifyItemReload(adapter_); 
} 
 
protected: 
  void OnGetChildId(ArkUI_NodeAdapterEvent* event) 
  { 
    auto index = OH_ArkUI_NodeAdapterEvent_GetItemIndex(event); 
    // 设置组件唯一标识符。 
    auto hash = std::hash<std::string>(); 
    OH_ArkUI_NodeAdapterEvent_SetNodeId(event, hash(data_[index])); 
  } 
void OnCreateNewChild(ArkUI_NodeAdapterEvent* event) 
{ 
  auto index = OH_ArkUI_NodeAdapterEvent_GetItemIndex(event); 
  ArkUI_NodeHandle listItem = nullptr; 
  if (!nodePool_.empty()) { 
    // 复用缓存 
    listItem = nodePool_.top(); 
    nodePool_.pop(); 
    // 更新数据 
    auto* text = nodeApi_->getFirstChild(listItem); 
    ArkUI_AttributeItem item { nullptr, 0, data_[index].c_str() }; 
    nodeApi_->setAttribute(text, NODE_TEXT_CONTENT, &item); 
  } else { 
    // 重新创建。 
    auto* text = nodeApi_->createNode(ARKUI_NODE_TEXT); 
    ArkUI_AttributeItem item { nullptr, 0, data_[index].c_str() }; 
    nodeApi_->setAttribute(text, NODE_TEXT_CONTENT, &item); 
    listItem = nodeApi_->createNode(ARKUI_NODE_LIST_ITEM); 
    nodeApi_->addChild(listItem, text); 
  } 
  OH_ArkUI_NodeAdapterEvent_SetCreatedNode(event, listItem); 
} 
void OnDisposeChild(ArkUI_NodeAdapterEvent* event) 
{ 
  auto* node = OH_ArkUI_NodeAdapterEvent_GetDisposeNode(event); 
  // 缓存节点 
  nodePool_.emplace(node); 
} 
private: 
  std::vector<std::string> data_; 
ArkUI_NativeNodeAPI_1* nodeApi_ = nullptr; 
ArkUI_NodeHandle list_ = nullptr; 
ArkUI_NodeAdapterHandle adapter_ = nullptr; 
UserCallback* adapterCallback_ = nullptr; 
// 节点缓存池,用于回收复用。 
std::stack<ArkUI_NodeHandle> nodePool_; 
}; 
typedef enum { 
  NODE_LIST_NODE_ITEM_ADAPTER, 
  NODE_LIST_CACHE_COUNT, 
  NODE_SWIPER_NODE_ITEM_ADAPTER, 
  NODE_SWIPER_CACHE_COUNT, 
  NODE_WATER_FLOW_NODE_ITEM_ADAPTER, 
  NODE_WATER_FLOW_CACHE_COUNT, 
} ArkUI_NodeAttributeType; 
// 定义组件适配器对象,用于滚动类组件的元素懒加载。 
typedef struct ArkUI_NodeAdapter* ArkUI_NodeAdapterHandle; 
// 定义适配器事件对象。 
typedef struct ArkUI_NodeAdapterEvent ArkUI_NodeAdapterEvent; 
typedef enum { 
  // Adapter适配器挂载到组件上。 
  NODE_ADAPTER_EVENT_ON_ATTACH_TO_NODE, 
  // Adapter适配器从组件上卸载。 
  NODE_ADAPTER_EVENT_ON_DETACH_TO_NODE, 
  // 获取组件标识符。 
  NODE_ADAPTER_EVENT_ON_GET_NODE_ID, 
  // 添加组件到Adapter中。 
  NODE_ADAPTER_EVENT_ON_ADD_NODE_TO_ADAPTER, 
  // 从Adapter中移除组件。 
  NODE_ADAPTER_EVENT_ON_REMOVE_NODE_FROM_ADAPTER, 
} ArkUI_NodeAdapterEventType; 
ArkUI_NodeAdapterHandle OH_ArkUI_NodeAdapter_Create(); 
void OH_ArkUI_NodeAdapter_Dispose(ArkUI_NodeAdapterHandle handle); 
// 设置Adapter中的元素总数。 
// 修改数量时默认会触发NotifyItemReloaded通知。 
int32_t OH_ArkUI_NodeAdapter_SetTotalNodeCount(ArkUI_NodeAdapterHandle handle, uint32_t size); 
uint32_t OH_ArkUI_NodeAdapter_GetTotalNodeCount(ArkUI_NodeAdapterHandle handle); 
// 注册Adapter相关回调事件,如元素需要创建,元素需要销毁等。新注册的覆盖老注册的。 
int32_t OH_ArkUI_NodeAdapter_RegisterEventReceiver( 
  ArkUI_NodeAdapterHandle handle, void* userData, void (*receiver)(ArkUI_NodeAdapterEvent* event)); 
// 反注册事件。 
void OH_ArkUI_NodeAdapter_UnregisterEventReceiver(ArkUI_NodeAdapterHandle handle); 
// 通知Adapter需要进行元素变化。 
// 通知适配器数据重载,在数据重载节点会触发NODE_ADAPTER_EVENT_ON_GET_NODE_ID事件获取可视区域和缓存区域组件
分享
微博
QQ
微信
回复
2024-08-09 19:29:44
相关问题
HarmonyOS ArkUI C-API有文档吗?
417浏览 • 1回复 待解决
HarmonyOS webview有非c-api的jsBridge吗?
423浏览 • 1回复 待解决
js api select组件如何使用
6976浏览 • 2回复 已解决
JS API web组件 怎么使用
5353浏览 • 1回复 待解决
HarmonyOS C++ VideoDecoder组件使用
184浏览 • 1回复 待解决
HarmonyOS 关于C API的问题
194浏览 • 1回复 待解决
List及ListItem组件使用
1747浏览 • 1回复 待解决
HarmonyOSList组件是否支持局部刷新
618浏览 • 1回复 待解决
HarmonyOS Web组件List的嵌套使用问题
262浏览 • 1回复 待解决
list 如何使用 lazyforeach
280浏览 • 1回复 待解决
使用List组件实现多列布局
554浏览 • 1回复 待解决
提问
该提问已有0人参与 ,帮助了0人