From 3c85df5cdb588ebc8129b12950df5fc4b0bcfbd5 Mon Sep 17 00:00:00 2001 From: liubihao Date: Tue, 1 Jul 2025 11:15:20 +0800 Subject: [PATCH 1/2] [Repeat] feat: default virtual scroll. Signed-off-by: liubihao --- .../arkoala-arkts/arkui-ohos/src/component/repeat.ts | 1 + .../arkui-ohos/src/handwritten/RepeatImpl.ts | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/repeat.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/repeat.ts index ac443e515fd..55719cfc734 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/repeat.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/repeat.ts @@ -34,6 +34,7 @@ export interface VirtualScrollOptions { totalCount?: number; reusable?: boolean; onTotalCount?: () => number; + disableVirtualScroll?: boolean; } export interface TemplateOptions { diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/RepeatImpl.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/RepeatImpl.ts index 2d277531449..d4abbad4e20 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/RepeatImpl.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/RepeatImpl.ts @@ -38,15 +38,15 @@ export function RepeatImpl( if (!repeat.itemGenFuncs_.get(RepeatEachFuncType)) { throw new Error('Repeat item builder function unspecified. Usage error!'); } - if (repeat.isVirtualScroll_) { + if (repeat.disableVirtualScroll_) { + nonVirtualRender(arr, repeat.itemGenFuncs_.get(RepeatEachFuncType)!, repeat.keyGenFunc_); + } else { const repeatId = __id(); const node = contextNode(); scheduleCallback(() => // postpone until node is attached repeat.templateCacheSize_.forEach((size: number, template: string) => node.setReusePoolSize(size, template + repeatId)) ); virtualRender(arr, repeat, repeatId); - } else { - nonVirtualRender(arr, repeat.itemGenFuncs_.get(RepeatEachFuncType)!, repeat.keyGenFunc_); } } @@ -141,7 +141,7 @@ export class RepeatAttributeImpl implements RepeatAttribute { templateCacheSize_: Map = new Map(); ttypeGenFunc_: TemplateTypedFunc = () => RepeatEachFuncType; reusable_: boolean = false; - isVirtualScroll_: boolean = false; + disableVirtualScroll_: boolean = false; each(itemGenerator: RepeatItemBuilder): RepeatAttributeImpl { if (itemGenerator === undefined || typeof itemGenerator !== 'function') { @@ -161,7 +161,7 @@ export class RepeatAttributeImpl implements RepeatAttribute { this.userDefinedTotal_ = options?.onTotalCount?.() ?? options?.totalCount; this.reusable_ = options?.reusable !== false; - this.isVirtualScroll_ = true; + this.disableVirtualScroll_ = options?.disableVirtualScroll ?? false; return this; } -- Gitee From 8fcff6fecfa52ad282cb38362631100dd587ff63 Mon Sep 17 00:00:00 2001 From: liubihao Date: Thu, 3 Jul 2025 17:04:35 +0800 Subject: [PATCH 2/2] [Repeat] feat: onlazyloading function. Signed-off-by: liubihao --- .../arkui-ohos/src/component/repeat.ts | 1 + .../arkui-ohos/src/handwritten/RepeatImpl.ts | 27 ++++++++++++++++--- .../base/lazy_compose_adapter.cpp | 5 ++++ .../components_ng/base/lazy_compose_adapter.h | 2 ++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/repeat.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/repeat.ts index 55719cfc734..5be8e11068e 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/repeat.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/repeat.ts @@ -33,6 +33,7 @@ export type TemplateTypedFunc = (item: T, index: number) => string; export interface VirtualScrollOptions { totalCount?: number; reusable?: boolean; + onLazyLoading?: (index: number) => void; onTotalCount?: () => number; disableVirtualScroll?: boolean; } diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/RepeatImpl.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/RepeatImpl.ts index d4abbad4e20..c442f5a52a3 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/RepeatImpl.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/RepeatImpl.ts @@ -80,6 +80,7 @@ class RepeatDataSource implements IDataSource { private arr_: RepeatArray; private listener_?: InternalListener; private total_: number; + private onLazyLoading_?: (index: number) => void; constructor(arr: RepeatArray) { this.arr_ = arr; @@ -112,12 +113,23 @@ class RepeatDataSource implements IDataSource { } getData(index: number): T { - if (index < 0 || index >= this.arr_.length) { + if (index < 0 || index >= this.total_) { throw new Error('index out of range. Application error!'); } + if (index >= this.arr_.length && index < this.total_) { + try { + this.onLazyLoading_?.(index); + } catch (error) { + console.error(`onLazyLoading function execute error: ${error}`); + } + } return this.arr_[index]; } + setOnLazyLoading(onLazyLoading?: (index: number) => void): void { + this.onLazyLoading_ = onLazyLoading; + } + registerDataChangeListener(listener: DataChangeListener): void { if (listener instanceof InternalListener) this.listener_ = listener as InternalListener; @@ -137,9 +149,12 @@ const RepeatEachFuncType: string = ''; export class RepeatAttributeImpl implements RepeatAttribute { itemGenFuncs_: Map> = new Map>(); keyGenFunc_?: (item: T, index: number) => string; - userDefinedTotal_?: number; - templateCacheSize_: Map = new Map(); + templateCacheSize_: Map = new Map(); // size of spare nodes for each template ttypeGenFunc_: TemplateTypedFunc = () => RepeatEachFuncType; + + userDefinedTotal_?: number; // if totalCount is specified + onLazyLoading_?: (index: number) => void; + reusable_: boolean = false; disableVirtualScroll_: boolean = false; @@ -160,6 +175,7 @@ export class RepeatAttributeImpl implements RepeatAttribute { virtualScroll(options?: VirtualScrollOptions): RepeatAttributeImpl { this.userDefinedTotal_ = options?.onTotalCount?.() ?? options?.totalCount; this.reusable_ = options?.reusable !== false; + this.onLazyLoading_ = options?.onLazyLoading; this.disableVirtualScroll_ = options?.disableVirtualScroll ?? false; return this; @@ -192,6 +208,11 @@ function virtualRender( ): void { let dataSource = remember(() => new RepeatDataSource(arr)); dataSource.updateData(arr, attributes.userDefinedTotal_ ?? arr.length); + if (!attributes.onLazyLoading_ && dataSource.totalCount() > arr.length) { + console.error(`(${repeatId}) totalCount must not exceed the array length without onLazyLoading callback.`); + } + dataSource.setOnLazyLoading(attributes.onLazyLoading_); + /** @memo */ const itemGen = (item: T, index: number): void => { const ri = new RepeatItemImpl(item, index); diff --git a/frameworks/core/components_ng/base/lazy_compose_adapter.cpp b/frameworks/core/components_ng/base/lazy_compose_adapter.cpp index be4fffff796..83a78c9494c 100644 --- a/frameworks/core/components_ng/base/lazy_compose_adapter.cpp +++ b/frameworks/core/components_ng/base/lazy_compose_adapter.cpp @@ -36,9 +36,14 @@ RefPtr LazyComposeAdapter::GetChild(uint32_t index) void LazyComposeAdapter::SetActiveRange(int32_t start, int32_t end) { + if (start == activeStart_ && end == activeEnd_) { + return; + } if (updateRange_) { updateRange_(start, end); } + activeStart_ = start; + activeEnd_ = end; items_.RemoveIf([start, end](const uint32_t& k, const auto& _) { const auto idx = static_cast(k); diff --git a/frameworks/core/components_ng/base/lazy_compose_adapter.h b/frameworks/core/components_ng/base/lazy_compose_adapter.h index b2f45334245..fb4a3f5add0 100644 --- a/frameworks/core/components_ng/base/lazy_compose_adapter.h +++ b/frameworks/core/components_ng/base/lazy_compose_adapter.h @@ -59,6 +59,8 @@ private: CreateItemCb createItem_; UpdateRangeCb updateRange_; int32_t totalCount_ = 0; + int32_t activeStart_ = -1; + int32_t activeEnd_ = -1; }; } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_LAZY_COMPOSE_ADAPTER_H -- Gitee