diff --git a/frameworks/bridge/declarative_frontend/jsview/js_repeat.cpp b/frameworks/bridge/declarative_frontend/jsview/js_repeat.cpp index 721410261c09389493d16fe9a8944cd89a02fc57..c3a31e8b5819d18f08770b1add65d2212d1a4bec 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_repeat.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_repeat.cpp @@ -125,6 +125,26 @@ void JSRepeat::AfterAddChild() RepeatModel::GetInstance()->AfterAddChild(); } +void JSRepeat::RecycleChild(const JSCallbackInfo& info) +{ + if ((info.Length() < 1) || !info[0]->IsNumber()) { + TAG_LOGW(AceLogTag::ACE_REPEAT, "Invalid arguments for Repeat.RecycleChild"); + return; + } + const auto index = info[0]->ToNumber(); + RepeatModel::GetInstance()->RecycleChild(index); +} + +void JSRepeat::ReuseChild(const JSCallbackInfo& info) +{ + if ((info.Length() < 1) || !info[0]->IsNumber()) { + TAG_LOGW(AceLogTag::ACE_REPEAT, "Invalid arguments for Repeat.ReuseChild"); + return; + } + const auto index = info[0]->ToNumber(); + RepeatModel::GetInstance()->ReuseChild(index); +} + void JSRepeat::JsParseItemDragEventHandler( const JsiExecutionContext& context, const JSRef& itemDragEventObj) { @@ -178,6 +198,8 @@ void JSRepeat::JSBind(BindingTarget globalObj) JSClass::StaticMethod("createNewChildFinish", &JSRepeat::CreateNewChildFinish); JSClass::StaticMethod("afterAddChild", &JSRepeat::AfterAddChild); JSClass::StaticMethod("onMove", &JSRepeat::OnMove); + JSClass::StaticMethod("recycle", &JSRepeat::RecycleChild); + JSClass::StaticMethod("reuse", &JSRepeat::ReuseChild); JSClass::Bind<>(globalObj); } diff --git a/frameworks/bridge/declarative_frontend/jsview/js_repeat.h b/frameworks/bridge/declarative_frontend/jsview/js_repeat.h index dc0950006479bfb9f5d86656a38ca78334d6247a..ffec7b6165078d911b59dd4f7dee783caadcd9de 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_repeat.h +++ b/frameworks/bridge/declarative_frontend/jsview/js_repeat.h @@ -38,6 +38,8 @@ public: // key: string // parentView?: JSView static void CreateNewChildFinish(const JSCallbackInfo& info); + static void RecycleChild(const JSCallbackInfo& info); + static void ReuseChild(const JSCallbackInfo& info); static void AfterAddChild(); static void OnMove(const JSCallbackInfo& info); static void JsParseItemDragEventHandler(const JsiExecutionContext& context, const JSRef& itemDragEventObj); diff --git a/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_foreach.d.ts b/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_foreach.d.ts index 01515f7903b8eb36bf8cb190f913619d74b888a4..4de1e47ba460df4cb0be868c9c0626428fd12e61 100644 --- a/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_foreach.d.ts +++ b/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_foreach.d.ts @@ -43,6 +43,8 @@ declare class RepeatNative { static createNewChildFinish(id: string): void; static afterAddChild(): void; static onMove(handler: (from: number, to: number) => void, eventHandler?: ItemDragEventHandler); + static reuse(index: number): void; + static recycle(index: number): void; } // Repeat.virtualScroll maps to C++ RepeatVirtualScrollNode diff --git a/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_repeat_impl.ts b/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_repeat_impl.ts index 6a399a0c630eb155b33da64ba645480418b3300e..9990ea603623fe9d98e7f3522523df5df5483411 100644 --- a/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_repeat_impl.ts +++ b/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_repeat_impl.ts @@ -33,14 +33,16 @@ class __RepeatImpl { /**/ public render(config: __RepeatConfig, isInitialRender: boolean): void { - this.arr_ = config.arr; + if (this.arr_ !== config.arr) { + this.arr_ = config.arr; + isInitialRender = true; + } this.itemGenFuncs_ = config.itemGenFuncs; this.ttypeGenFunc_ = config.ttypeGenFunc; this.keyGenFunction_ = config.keyGenFunc; this.mkRepeatItem_ = config.mkRepeatItem; this.onMoveHandler_ = config.onMoveHandler; this.itemDragEventHandler = config.itemDragEventHandler; - isInitialRender ? this.initialRender() : this.reRender(); } @@ -126,6 +128,7 @@ class __RepeatImpl { itemInfo.repeatItem = oldRepeatItem; stateMgmtConsole.debug(`__RepeatImpl: new: key ${key} reuse key ${reuseKey} ${oldKeyIndex}->${index}`); + RepeatNative.recycle(oldKeyIndex); itemInfo.repeatItem.updateItem(item); itemInfo.repeatItem.updateIndex(index); @@ -135,6 +138,7 @@ class __RepeatImpl { // TBD moveChild() only when item types are same // C++ mv from tempChildren[oldIndex] to end of children_ RepeatNative.moveChild(oldKeyIndex); + RepeatNative.reuse(oldKeyIndex); } else { // case #3: // new array item, there are no deleted array items diff --git a/frameworks/core/components_ng/syntax/repeat_model.h b/frameworks/core/components_ng/syntax/repeat_model.h index 40057fae425c58f246a35ffdeb2e646ee929e773..c3a69b388918ce25d71433685c8c90b95e140440 100644 --- a/frameworks/core/components_ng/syntax/repeat_model.h +++ b/frameworks/core/components_ng/syntax/repeat_model.h @@ -39,7 +39,10 @@ public: virtual void MoveChild(uint32_t fromIndex) = 0; virtual void CreateNewChildStart(const std::string& key) = 0; virtual void CreateNewChildFinish(const std::string& key) = 0; + virtual void RecycleChild(uint32_t index) = 0; + virtual void ReuseChild(uint32_t index) = 0; virtual void AfterAddChild() = 0; + virtual void OnMove(std::function&& onMove) = 0; virtual void SetItemDragHandler(std::function&& onLongPress, std::function&& onDragStart, std::function&& onMoveThrough, diff --git a/frameworks/core/components_ng/syntax/repeat_model_ng.cpp b/frameworks/core/components_ng/syntax/repeat_model_ng.cpp index 8a4becb94c45ed680ee1c6428e36ff4233b29531..4656f6b9c0579b7eed5e46f24e72b828f78dc86e 100644 --- a/frameworks/core/components_ng/syntax/repeat_model_ng.cpp +++ b/frameworks/core/components_ng/syntax/repeat_model_ng.cpp @@ -71,6 +71,22 @@ void RepeatModelNG::CreateNewChildFinish(const std::string& key) stack->PopContainer(); } +void RepeatModelNG::RecycleChild(uint32_t index) +{ + auto* stack = ViewStackProcessor::GetInstance(); + auto node = AceType::DynamicCast(stack->GetMainElementNode()); + CHECK_NULL_VOID(node); + node->RecycleChild(index); +} + +void RepeatModelNG::ReuseChild(uint32_t index) +{ + auto* stack = ViewStackProcessor::GetInstance(); + auto node = AceType::DynamicCast(stack->GetMainElementNode()); + CHECK_NULL_VOID(node); + node->ReuseChild(index); +} + void RepeatModelNG::AfterAddChild() { auto* stack = ViewStackProcessor::GetInstance(); diff --git a/frameworks/core/components_ng/syntax/repeat_model_ng.h b/frameworks/core/components_ng/syntax/repeat_model_ng.h index 8c09bfe6891ddc137e702b1754c34422a257b868..f8a5c4a4fc3040e51226489dfde9a61b48f56238 100644 --- a/frameworks/core/components_ng/syntax/repeat_model_ng.h +++ b/frameworks/core/components_ng/syntax/repeat_model_ng.h @@ -38,6 +38,8 @@ public: void MoveChild(uint32_t fromIndex) override; void CreateNewChildStart(const std::string& key) override; void CreateNewChildFinish(const std::string& key) override; + void RecycleChild(uint32_t index) override; + void ReuseChild(uint32_t index) override; void AfterAddChild() override; void OnMove(std::function&& onMove) override; diff --git a/frameworks/core/components_ng/syntax/repeat_node.cpp b/frameworks/core/components_ng/syntax/repeat_node.cpp index 6cb155b00924fe0a513a00169fa0026930321845..17cb051f6ac68b82df42aec51527930c93b967a7 100644 --- a/frameworks/core/components_ng/syntax/repeat_node.cpp +++ b/frameworks/core/components_ng/syntax/repeat_node.cpp @@ -84,6 +84,22 @@ void RepeatNode::FinishRepeatRender(std::list& removedElmtId) } } +void RepeatNode::RecycleChild(uint32_t index) +{ + if (index < tempChildrenOfRepeat_.size()) { + auto& node = tempChildrenOfRepeat_.at(index); + node->OnRecycle(); + } +} + +void RepeatNode::ReuseChild(uint32_t index) +{ + if (index < tempChildrenOfRepeat_.size()) { + auto& node = tempChildrenOfRepeat_.at(index); + node->OnReuse(); + } +} + void RepeatNode::AfterAddChild() { if (!ModifyChildren().empty()) { diff --git a/frameworks/core/components_ng/syntax/repeat_node.h b/frameworks/core/components_ng/syntax/repeat_node.h index 947f994393475a6e8ffcc88cf96b8dba3fb7132e..e80450b6390d85ea611c11fdbde9e10d05e7cf3a 100644 --- a/frameworks/core/components_ng/syntax/repeat_node.h +++ b/frameworks/core/components_ng/syntax/repeat_node.h @@ -63,6 +63,9 @@ public: ids_ = std::move(ids); } + void ReuseChild(uint32_t index); + void RecycleChild(uint32_t index); + void AfterAddChild(); void SetOnMove(std::function&& onMove); void SetItemDragHandler(std::function&& onLongPress, std::function&& onDragStart,