Skip to content

Commit 6d206a3

Browse files
hannojgfacebook-github-bot
authored andcommitted
Add workaround for android API 33 ANR when inverting ScrollView (#38071)
Summary: This PR is a result of this PR, which got merged but then reverted: - #37913 We are trying to implement a workaround for #35350, so react-native users on android API 33+ can use `<FlatList inverted={true} />` without running into ANRs. This is the native part, where we add a new internal prop named `isInvertedVirtualizedList`, which can in a follow up change be used to achieve the final fix as proposed in #37913 However as NickGerleman pointed out, its important that we first ship the native change. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [ANDROID] [ADDED] - Native part of fixing ANR when having an inverted FlatList on android API 33+ Pull Request resolved: #38071 Test Plan: - Check the RN tester app and see that scrollview is still working as expected - Add the `isInvertedVirtualizedList` prop as test to a scrollview and see how the scrollbar will change position. Reviewed By: rozele Differential Revision: D47062200 Pulled By: NickGerleman fbshipit-source-id: d20eebeec757d9aaeced8561f53556bbb4a492e4
1 parent ecb58a1 commit 6d206a3

File tree

6 files changed

+37
-1
lines changed

6 files changed

+37
-1
lines changed

packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
8686
process: require('../../StyleSheet/processColor').default,
8787
},
8888
pointerEvents: true,
89+
isInvertedVirtualizedList: true,
8990
},
9091
}
9192
: {

packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export type ScrollViewNativeProps = $ReadOnly<{
4141
endFillColor?: ?ColorValue,
4242
fadingEdgeLength?: ?number,
4343
indicatorStyle?: ?('default' | 'black' | 'white'),
44+
isInvertedVirtualizedList?: ?boolean,
4445
keyboardDismissMode?: ?('none' | 'on-drag' | 'interactive'),
4546
maintainVisibleContentPosition?: ?$ReadOnly<{
4647
minIndexForVisible: number,

packages/react-native/Libraries/Components/ScrollView/ScrollViewViewConfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const ScrollViewViewConfig = {
4646
fadingEdgeLength: true,
4747
indicatorStyle: true,
4848
inverted: true,
49+
isInvertedVirtualizedList: true,
4950
keyboardDismissMode: true,
5051
maintainVisibleContentPosition: true,
5152
maximumZoomScale: true,

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,4 +379,22 @@ public void setPointerEvents(ReactScrollView view, @Nullable String pointerEvent
379379
public void setScrollEventThrottle(ReactScrollView view, int scrollEventThrottle) {
380380
view.setScrollEventThrottle(scrollEventThrottle);
381381
}
382+
383+
@ReactProp(name = "isInvertedVirtualizedList")
384+
public void setIsInvertedVirtualizedList(ReactScrollView view, boolean applyFix) {
385+
// Usually when inverting the scroll view we are using scaleY: -1 on the list
386+
// and on the parent container. HOWEVER, starting from android API 33 there is
387+
// a bug that can cause an ANR due to that. Thus we are using different transform
388+
// commands to circumvent the ANR. This however causes the vertical scrollbar to
389+
// be on the wrong side. Thus we are moving it to the other side, when the list
390+
// is inverted.
391+
// See also:
392+
// - https://github.com/facebook/react-native/issues/35350
393+
// - https://issuetracker.google.com/issues/287304310
394+
if (applyFix) {
395+
view.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT);
396+
} else {
397+
view.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_DEFAULT);
398+
}
399+
}
382400
}

packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,15 @@ ScrollViewProps::ScrollViewProps(
319319
rawProps,
320320
"scrollToOverflowEnabled",
321321
sourceProps.scrollToOverflowEnabled,
322+
{})),
323+
isInvertedVirtualizedList(
324+
CoreFeatures::enablePropIteratorSetter
325+
? sourceProps.isInvertedVirtualizedList
326+
: convertRawProp(
327+
context,
328+
rawProps,
329+
"isInvertedVirtualizedList",
330+
sourceProps.isInvertedVirtualizedList,
322331
{})) {}
323332

324333
void ScrollViewProps::setProp(
@@ -368,6 +377,7 @@ void ScrollViewProps::setProp(
368377
RAW_SET_PROP_SWITCH_CASE_BASIC(snapToEnd);
369378
RAW_SET_PROP_SWITCH_CASE_BASIC(contentInsetAdjustmentBehavior);
370379
RAW_SET_PROP_SWITCH_CASE_BASIC(scrollToOverflowEnabled);
380+
RAW_SET_PROP_SWITCH_CASE_BASIC(isInvertedVirtualizedList);
371381
}
372382
}
373383

@@ -492,7 +502,11 @@ SharedDebugStringConvertibleList ScrollViewProps::getDebugProps() const {
492502
debugStringConvertibleItem(
493503
"snapToStart", snapToStart, defaultScrollViewProps.snapToStart),
494504
debugStringConvertibleItem(
495-
"snapToEnd", snapToEnd, defaultScrollViewProps.snapToEnd)};
505+
"snapToEnd", snapToEnd, defaultScrollViewProps.snapToEnd),
506+
debugStringConvertibleItem(
507+
"isInvertedVirtualizedList",
508+
snapToEnd,
509+
defaultScrollViewProps.isInvertedVirtualizedList)};
496510
}
497511
#endif
498512

packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class ScrollViewProps final : public ViewProps {
6868
ContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior{
6969
ContentInsetAdjustmentBehavior::Never};
7070
bool scrollToOverflowEnabled{false};
71+
bool isInvertedVirtualizedList{false};
7172

7273
#pragma mark - DebugStringConvertible
7374

0 commit comments

Comments
 (0)