From 989177d5ad4af052a58899cbc4a1a1b902f7a438 Mon Sep 17 00:00:00 2001 From: islandryu Date: Sun, 1 May 2022 23:55:10 +0900 Subject: [PATCH 1/3] Fixed a bug that items disappear when zooming VirtualizedList --- Libraries/Lists/VirtualizeUtils.js | 10 +++++++--- Libraries/Lists/VirtualizedList.js | 5 +++++ Libraries/Lists/VirtualizedListContext.js | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Libraries/Lists/VirtualizeUtils.js b/Libraries/Lists/VirtualizeUtils.js index 6e50e62b9cabc9..85d50539db6200 100644 --- a/Libraries/Lists/VirtualizeUtils.js +++ b/Libraries/Lists/VirtualizeUtils.js @@ -25,12 +25,13 @@ export function elementsThatOverlapOffsets( offset: number, ... }, + zoomScale: number, ): Array { const out = []; let outLength = 0; for (let ii = 0; ii < itemCount; ii++) { const frame = getFrameMetrics(ii); - const trailingOffset = frame.offset + frame.length; + const trailingOffset = (frame.offset + frame.length) * zoomScale; for (let kk = 0; kk < offsets.length; kk++) { if (out[kk] == null && trailingOffset >= offsets[kk]) { out[kk] = ii; @@ -104,6 +105,7 @@ export function computeWindowedRenderLimits( offset: number, velocity: number, visibleLength: number, + zoomScale: number, ... }, ): { @@ -115,7 +117,7 @@ export function computeWindowedRenderLimits( if (itemCount === 0) { return prev; } - const {offset, velocity, visibleLength} = scrollMetrics; + const {offset, velocity, visibleLength, zoomScale} = scrollMetrics; // Start with visible area, then compute maximum overscan region by expanding from there, biased // in the direction of scroll. Total overscan area is capped, which should cap memory consumption @@ -136,7 +138,8 @@ export function computeWindowedRenderLimits( ); const overscanEnd = Math.max(0, visibleEnd + leadFactor * overscanLength); - const lastItemOffset = getFrameMetricsApprox(itemCount - 1).offset; + const lastItemOffset = + getFrameMetricsApprox(itemCount - 1).offset * zoomScale; if (lastItemOffset < overscanBegin) { // Entire list is before our overscan window return { @@ -150,6 +153,7 @@ export function computeWindowedRenderLimits( [overscanBegin, visibleBegin, visibleEnd, overscanEnd], itemCount, getFrameMetricsApprox, + zoomScale, ); overscanFirst = overscanFirst == null ? 0 : overscanFirst; first = first == null ? Math.max(0, overscanFirst) : first; diff --git a/Libraries/Lists/VirtualizedList.js b/Libraries/Lists/VirtualizedList.js index 258a12e66b613c..84920ec7dbdd49 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -1222,6 +1222,7 @@ class VirtualizedList extends React.PureComponent { timestamp: 0, velocity: 0, visibleLength: 0, + zoomScale: 1, }; _scrollRef: ?React.ElementRef = null; _sentEndForContentLength = 0; @@ -1618,6 +1619,9 @@ class VirtualizedList extends React.PureComponent { ); this._hasWarned.perf = true; } + + const zoomScale = e.nativeEvent.zoomScale; + this._scrollMetrics = { contentLength, dt, @@ -1626,6 +1630,7 @@ class VirtualizedList extends React.PureComponent { timestamp, velocity, visibleLength, + zoomScale, }; this._updateViewableItems(this.props.data); if (!this.props) { diff --git a/Libraries/Lists/VirtualizedListContext.js b/Libraries/Lists/VirtualizedListContext.js index d51a79244a0330..1d38901927f228 100644 --- a/Libraries/Lists/VirtualizedListContext.js +++ b/Libraries/Lists/VirtualizedListContext.js @@ -47,6 +47,7 @@ type Context = $ReadOnly<{ timestamp: number, velocity: number, visibleLength: number, + ... }, horizontal: ?boolean, getOutermostParentListRef: () => VirtualizedList, From 1f6cf50e25570d428e75ab640a7ced0ca44f8cf3 Mon Sep 17 00:00:00 2001 From: islandryu Date: Fri, 6 May 2022 15:06:22 +0900 Subject: [PATCH 2/3] fix test --- Libraries/Lists/__tests__/VirtualizeUtils-test.js | 12 ++++++------ Libraries/Lists/__tests__/VirtualizedList-test.js | 11 +++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Libraries/Lists/__tests__/VirtualizeUtils-test.js b/Libraries/Lists/__tests__/VirtualizeUtils-test.js index 88eb4f068c46a8..c700d599100e93 100644 --- a/Libraries/Lists/__tests__/VirtualizeUtils-test.js +++ b/Libraries/Lists/__tests__/VirtualizeUtils-test.js @@ -48,9 +48,9 @@ describe('elementsThatOverlapOffsets', function () { offset: 100 * index, }; } - expect(elementsThatOverlapOffsets(offsets, 100, getFrameMetrics)).toEqual([ - 0, 2, 3, 4, - ]); + expect( + elementsThatOverlapOffsets(offsets, 100, getFrameMetrics, 1), + ).toEqual([0, 2, 3, 4]); }); it('handles variable length', function () { const offsets = [150, 250, 900]; @@ -62,7 +62,7 @@ describe('elementsThatOverlapOffsets', function () { {offset: 950, length: 150}, ]; expect( - elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii]), + elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii], 1), ).toEqual([1, 1, 3]); }); it('handles out of bounds', function () { @@ -73,7 +73,7 @@ describe('elementsThatOverlapOffsets', function () { {offset: 250, length: 100}, ]; expect( - elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii]), + elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii], 1), ).toEqual([1]); }); it('errors on non-increasing offsets', function () { @@ -84,7 +84,7 @@ describe('elementsThatOverlapOffsets', function () { {offset: 250, length: 100}, ]; expect(() => { - elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii]); + elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii], 1); }).toThrowErrorMatchingSnapshot(); }); }); diff --git a/Libraries/Lists/__tests__/VirtualizedList-test.js b/Libraries/Lists/__tests__/VirtualizedList-test.js index 9f902f180c7fbc..5354df93f7f7b5 100644 --- a/Libraries/Lists/__tests__/VirtualizedList-test.js +++ b/Libraries/Lists/__tests__/VirtualizedList-test.js @@ -384,7 +384,7 @@ describe('VirtualizedList', () => { const instance = component.getInstance(); - instance._onLayout({nativeEvent: {layout}}); + instance._onLayout({nativeEvent: {layout, zoomScale: 1}}); const initialContentHeight = props.initialNumToRender * ITEM_HEIGHT; @@ -1490,7 +1490,7 @@ it('calls _onCellLayout properly', () => { ); const cell = virtualList._cellRefs.i4; const event = { - nativeEvent: {layout: {x: 0, y: 0, width: 50, height: 50}}, + nativeEvent: {layout: {x: 0, y: 0, width: 50, height: 50}, zoomScale: 1}, }; cell._onLayout(event); expect(mock).toHaveBeenCalledWith(event, 'i4', 3); @@ -1544,7 +1544,9 @@ function simulateLayout(component, args) { function simulateViewportLayout(component, dimensions) { lastViewportLayout = dimensions; - component.getInstance()._onLayout({nativeEvent: {layout: dimensions}}); + component + .getInstance() + ._onLayout({nativeEvent: {layout: dimensions}, zoomScale: 1}); } function simulateContentLayout(component, dimensions) { @@ -1558,7 +1560,7 @@ function simulateCellLayout(component, items, itemIndex, dimensions) { const instance = component.getInstance(); const cellKey = instance._keyExtractor(items[itemIndex], itemIndex); instance._onCellLayout( - {nativeEvent: {layout: dimensions}}, + {nativeEvent: {layout: dimensions, zoomScale: 1}}, cellKey, itemIndex, ); @@ -1570,6 +1572,7 @@ function simulateScroll(component, position) { contentOffset: position, contentSize: lastContentLayout, layoutMeasurement: lastViewportLayout, + zoomScale: 1, }, }); } From c721cf6351e82fd9fef5b615ff8615cc1de04a7d Mon Sep 17 00:00:00 2001 From: islandryu Date: Fri, 6 May 2022 16:41:37 +0900 Subject: [PATCH 3/3] fix type --- Libraries/Lists/VirtualizedListContext.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Lists/VirtualizedListContext.js b/Libraries/Lists/VirtualizedListContext.js index 1d38901927f228..308f6a20d19a54 100644 --- a/Libraries/Lists/VirtualizedListContext.js +++ b/Libraries/Lists/VirtualizedListContext.js @@ -47,7 +47,7 @@ type Context = $ReadOnly<{ timestamp: number, velocity: number, visibleLength: number, - ... + zoomScale: number, }, horizontal: ?boolean, getOutermostParentListRef: () => VirtualizedList,