From 824c1c6d073ba53aab350bc617169ba04e568b19 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Fri, 11 Aug 2023 13:57:21 -0700 Subject: [PATCH] Math.floor the top, bottom values of an item in a VirtualizedList (#38962) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/38962 Changelog: [General][Changed] Math.floor the top and bottom dimensions of a cell item when determining viewability. Reviewed By: NickGerleman Differential Revision: D48212402 fbshipit-source-id: 0ba7d5c218477c257a4504391940d916e4832f91 --- .../Lists/ViewabilityHelper.js | 5 ++-- .../Lists/__tests__/ViewabilityHelper-test.js | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/virtualized-lists/Lists/ViewabilityHelper.js b/packages/virtualized-lists/Lists/ViewabilityHelper.js index cae7c0bd685572..f210b030d0952a 100644 --- a/packages/virtualized-lists/Lists/ViewabilityHelper.js +++ b/packages/virtualized-lists/Lists/ViewabilityHelper.js @@ -144,8 +144,9 @@ class ViewabilityHelper { if (!metrics) { continue; } - const top = metrics.offset - scrollOffset; - const bottom = top + metrics.length; + const top = Math.floor(metrics.offset - scrollOffset); + const bottom = Math.floor(top + metrics.length); + if (top < viewportHeight && bottom > 0) { firstVisible = idx; if ( diff --git a/packages/virtualized-lists/Lists/__tests__/ViewabilityHelper-test.js b/packages/virtualized-lists/Lists/__tests__/ViewabilityHelper-test.js index 08423c52cc275a..9e7f591b91b94a 100644 --- a/packages/virtualized-lists/Lists/__tests__/ViewabilityHelper-test.js +++ b/packages/virtualized-lists/Lists/__tests__/ViewabilityHelper-test.js @@ -441,4 +441,29 @@ describe('onUpdate', function () { viewableItems: [{isViewable: true, key: 'c'}], }); }); + + it('should account for imprecision on measurements of width of viewport and item', () => { + // This test assures we round down the calculations of the item cell layout + // to avoid cases of imprecison when measuring layout + const helper = new ViewabilityHelper({itemVisiblePercentThreshold: 100}); + const testProps = { + getItemCount: () => 1, + data: ['Item'], + }; + const listMetrics = { + getCellMetrics: () => ({ + index: 0, + length: 147.4285888671875, + offset: 1767.6190185546875, + isMounted: true, + }), + }; + const viewableIndices = helper.computeViewableItems( + testProps, + 1503.61901855, // scrollOffset + 411.4285583496094, // viewportHeight (viewportWidth depending on scrolling axis) + listMetrics, + ); + expect(viewableIndices).toEqual([0]); + }); });