From bf936109b396892d6341a3d891137c6314757440 Mon Sep 17 00:00:00 2001 From: ryuyutyo Date: Mon, 26 Jun 2023 22:44:44 +0800 Subject: [PATCH] feat: update --- packages/data-model/src/ItemMeta.ts | 10 +++++ packages/data-model/src/ListDimensions.ts | 44 ++++++++++++++----- .../data-model/src/types/Dimensions.types.ts | 1 + 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/packages/data-model/src/ItemMeta.ts b/packages/data-model/src/ItemMeta.ts index 91e8b98f..217243b3 100644 --- a/packages/data-model/src/ItemMeta.ts +++ b/packages/data-model/src/ItemMeta.ts @@ -24,6 +24,7 @@ class ItemMeta extends ViewabilityItemMeta { readonly getMetaOnViewableItemsChanged?: any; readonly _ownerId: string; readonly _canIUseRIC?: boolean; + private _isApproximateLayout: boolean; constructor(props: { onViewable?: StateEventListener; @@ -60,6 +61,7 @@ class ItemMeta extends ViewabilityItemMeta { : {}; this._canIUseRIC = canIUseRIC; + this._isApproximateLayout = false; // this.addStateListener = this.addStateListener.bind(this); // this.removeStateListener = this.removeStateListener.bind(this); @@ -70,6 +72,14 @@ class ItemMeta extends ViewabilityItemMeta { return this._id; } + get isApproximatedLayout() { + return this._isApproximateLayout; + } + + set isApproximateLayout(value: boolean) { + this._isApproximateLayout = value; + } + setLayout(layout: ItemLayout) { this._layout = layout; } diff --git a/packages/data-model/src/ListDimensions.ts b/packages/data-model/src/ListDimensions.ts index 8a753b8c..c9c729a4 100644 --- a/packages/data-model/src/ListDimensions.ts +++ b/packages/data-model/src/ListDimensions.ts @@ -48,6 +48,7 @@ import memoizeOne from 'memoize-one'; import shallowEqual from '@x-oasis/shallow-equal'; import shallowArrayEqual from '@x-oasis/shallow-array-equal'; import StillnessHelper from './utils/StillnessHelper'; +import defaultBooleanValue from '@x-oasis/default-boolean-value'; class ListDimensions extends BaseDimensions { private _data: Array = []; @@ -113,6 +114,9 @@ class ListDimensions extends BaseDimensions { state: ListState ) => RecycleStateResult; + private _itemApproximateLength: number; + private _approximateMode: boolean; + constructor(props: ListDimensionsProps) { super({ ...props, @@ -120,6 +124,7 @@ class ListDimensions extends BaseDimensions { }); const { store, + recycleEnabled, data = [], deps = [], keyExtractor, @@ -140,18 +145,20 @@ class ListDimensions extends BaseDimensions { onEndReachedTimeoutThreshold, distanceFromEndThresholdValue, onEndReachedHandlerTimeoutThreshold, + useItemApproximateLength, maxCountOfHandleOnEndReachedAfterStillness, } = props; - // this.approximateLayoutGetter = this.approximateLayoutGetter.bind(this) + this._keyExtractor = keyExtractor; - this._getItemLayout = - getItemLayout || - (itemApproximateLength - ? (_, index) => ({ - length: itemApproximateLength, - index, - }) - : null); + this._itemApproximateLength = itemApproximateLength || 0; + this._getItemLayout = getItemLayout; + this._approximateMode = recycleEnabled + ? defaultBooleanValue( + useItemApproximateLength, + typeof this._getItemLayout !== 'function' || + !this._itemApproximateLength + ) + : false; this._getItemSeparatorLength = getItemSeparatorLength; // for ListItem include a basic items condition this._parentItemsDimensions = parentItemsDimensions; @@ -473,6 +480,12 @@ class ListDimensions extends BaseDimensions { const oldLength = this.intervalTree.getHeap()[1]; this.intervalTree.set(index, length); const nextLength = this.intervalTree.getHeap()[1]; + const len = this.intervalTree.getMaxUsefulLength(); + + if (typeof nextLength === 'number') + this._itemApproximateLength = this.normalizeLengthNumber( + nextLength / Math.max(len, 1) + ); if (oldLength !== nextLength && this._listGroupDimension) { this._listGroupDimension.recalculateDimensionsIntervalTreeBatchinator.schedule(); @@ -521,6 +534,15 @@ class ListDimensions extends BaseDimensions { canIUseRIC: this.canIUseRIC, }); + if (this._approximateMode) { + meta.setLayout({ x: 0, y: 0, height: 0, width: 0 }); + this._selectValue.setLength( + meta.getLayout(), + this._itemApproximateLength + ); + meta.isApproximateLayout = true; + } + if (typeof this._getItemLayout === 'function') { const { length } = this._getItemLayout(data, index); // only List with getItemLayout has default layout value @@ -884,6 +906,7 @@ class ListDimensions extends BaseDimensions { let length = this.normalizeLengthNumber(info); if (this._selectValue.selectLength(meta.getLayout() || {}) !== length) { this._selectValue.setLength(meta.ensureLayout(), length); + meta.isApproximateLayout = false; if (index !== this._data.length - 1) { length = meta.getSeparatorLength() + length; @@ -918,6 +941,7 @@ class ListDimensions extends BaseDimensions { ); let length = this._selectValue.selectLength((_info as ItemLayout) || {}); meta.setLayout(_info as ItemLayout); + meta.isApproximateLayout = false; // 只有关心的值发生变化时,才会再次触发setIntervalTreeValue if (currentLength !== length && _update) { if (index !== this._data.length - 1) { @@ -1228,7 +1252,7 @@ class ListDimensions extends BaseDimensions { // remainingPosition // ); - if (this._getItemLayout) { + if (this._getItemLayout || this._approximateMode) { if (Math.abs(velocity) <= 1) { this.updateIndices(targetIndices, { safeRange, diff --git a/packages/data-model/src/types/Dimensions.types.ts b/packages/data-model/src/types/Dimensions.types.ts index 599b61b1..1a81e663 100644 --- a/packages/data-model/src/types/Dimensions.types.ts +++ b/packages/data-model/src/types/Dimensions.types.ts @@ -92,6 +92,7 @@ export type ListDimensionsProps = { canIUseRIC?: boolean; itemApproximateLength?: number; + useItemApproximateLength?: boolean; } & BaseDimensionsProps & OnEndReachedHelperProps;