From 58c81f9573ffbe919ab40dfc5bb25e17804edf77 Mon Sep 17 00:00:00 2001 From: "o.o.c" <568071718@qq.com> Date: Sun, 19 Jan 2025 10:07:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=8E=B7=E5=8F=96=E5=8F=AF?= =?UTF-8?q?=E7=94=A8=E8=8A=82=E7=82=B9=E6=97=B6=E7=9A=84=E9=80=BB=E8=BE=91?= =?UTF-8?q?=202x?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- list-2x/assets/lib/yx-collection-view.ts | 39 +++++++++++++++++++----- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/list-2x/assets/lib/yx-collection-view.ts b/list-2x/assets/lib/yx-collection-view.ts index e4a9230..e598fe2 100644 --- a/list-2x/assets/lib/yx-collection-view.ts +++ b/list-2x/assets/lib/yx-collection-view.ts @@ -299,6 +299,24 @@ class _scroll_view extends ScrollView { } } +class _yx_node_pool extends NodePool { + getAtIdx(indexPath: YXIndexPath, ...args: any[]): Node | null { + const nodes: Node[] = this['_pool'] + for (let index = 0; index < nodes.length; index++) { + const obj = nodes[index]; + let comp = obj.getComponent(_yx_node_element_comp) + if (comp && comp.attributes.indexPath.equals(indexPath)) { + nodes.splice(index, 1) + // @ts-ignore + const handler = this.poolHandlerComp ? obj.getComponent(this.poolHandlerComp) : null; + if (handler && handler.reuse) { handler.reuse(arguments); } + return obj + } + } + return null + } +} + /** * 节点的布局属性 */ @@ -642,7 +660,7 @@ export class YXCollectionView extends Component { registerCell(identifier: string, maker: () => Node, poolComp: (new (...args: any[]) => YXCollectionViewCell) | string | null = null) { let elementCategory: typeof YXLayoutAttributes.prototype.elementCategory = 'Cell' identifier = elementCategory + identifier - let pool = new NodePool(poolComp) + let pool = new _yx_node_pool(poolComp) this.pools.set(identifier, pool) this.makers.set(identifier, maker) } @@ -653,7 +671,7 @@ export class YXCollectionView extends Component { registerSupplementary(identifier: string, maker: () => Node, poolComp: (new (...args: any[]) => YXCollectionViewCell) | string | null = null) { let elementCategory: typeof YXLayoutAttributes.prototype.elementCategory = 'Supplementary' identifier = elementCategory + identifier - let pool = new NodePool(poolComp) + let pool = new _yx_node_pool(poolComp) this.pools.set(identifier, pool) this.makers.set(identifier, maker) } @@ -671,19 +689,21 @@ export class YXCollectionView extends Component { /** * 通过标识符从重用池里取出一个可用的 cell 节点 * @param identifier 注册时候的标识符 + * @param indexPath 可选,尝试通过 indexPath 获取刷新之前的节点 (尽可能的保证刷新前和刷新后这个位置仍然是同一个节点),避免节点复用导致的刷新闪烁问题 */ - dequeueReusableCell(identifier: string): Node { - return this._dequeueReusableElement(identifier, 'Cell') + dequeueReusableCell(identifier: string, indexPath: YXIndexPath = null): Node { + return this._dequeueReusableElement(identifier, 'Cell', indexPath) } /** * 通过标识符从重用池里取出一个可用的 supplementary 节点 * @param identifier 注册时候的标识符 + * @param indexPath 可选,尝试通过 indexPath 获取刷新之前的节点 (尽可能的保证刷新前和刷新后这个位置仍然是同一个节点),避免节点复用导致的刷新闪烁问题 */ - dequeueReusableSupplementary(identifier: string): Node { - return this._dequeueReusableElement(identifier, 'Supplementary') + dequeueReusableSupplementary(identifier: string, indexPath: YXIndexPath = null): Node { + return this._dequeueReusableElement(identifier, 'Supplementary', indexPath) } - private _dequeueReusableElement(identifier: string, elementCategory: typeof YXLayoutAttributes.prototype.elementCategory) { + private _dequeueReusableElement(identifier: string, elementCategory: typeof YXLayoutAttributes.prototype.elementCategory, indexPath: YXIndexPath = null) { identifier = elementCategory + identifier let pool = this.pools.get(identifier) if (pool == null) { @@ -691,6 +711,11 @@ export class YXCollectionView extends Component { } let result: Node = null + // 尝试从重用池获取 (牺牲一点性能,尝试通过 indexPath 获取对应的节点,防止刷新闪烁的问题) + if (result == null && indexPath && pool instanceof _yx_node_pool) { + result = pool.getAtIdx(indexPath) + } + // 尝试从重用池获取 if (result == null) { result = pool.get()