From 94cb533dbbd47fae9d0265e15b388495e239c5bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 26 Jun 2023 18:31:15 +0200 Subject: [PATCH 1/4] add internalAndroidApplyInvertedFix prop See also: https://github.com/facebook/react-native/pull/37913#issuecomment-1603018280 --- .../views/scroll/ReactScrollViewManager.java | 18 ++++++++++++++++++ .../components/scrollview/ScrollViewProps.cpp | 16 +++++++++++++++- .../components/scrollview/ScrollViewProps.h | 1 + 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java index 46e0ccf36c6e..2f0d6c93ed7d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java @@ -379,4 +379,22 @@ public void setPointerEvents(ReactScrollView view, @Nullable String pointerEvent public void setScrollEventThrottle(ReactScrollView view, int scrollEventThrottle) { view.setScrollEventThrottle(scrollEventThrottle); } + + @ReactProp(name = "internalAndroidApplyInvertedFix") + public void setInternalAndroidApplyInvertedFix(ReactScrollView view, boolean applyFix) { + // Usually when inverting the scroll view we are using scaleY: -1 on the list + // and on the parent container. HOWEVER, starting from android API 33 there is + // a bug that can cause an ANR due to that. Thus we are using different transform + // commands to circumvent the ANR. This however causes the vertical scrollbar to + // be on the wrong side. Thus we are moving it to the other side, when the list + // is inverted. + // See also: + // - https://github.com/facebook/react-native/issues/35350 + // - https://issuetracker.google.com/issues/287304310 + if (applyFix) { + view.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT); + } else { + view.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_DEFAULT); + } + } } diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp index fb70d8a6176c..03463afdfdbe 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp @@ -319,6 +319,15 @@ ScrollViewProps::ScrollViewProps( rawProps, "scrollToOverflowEnabled", sourceProps.scrollToOverflowEnabled, + {})), + internalAndroidApplyInvertedFix( + CoreFeatures::enablePropIteratorSetter + ? sourceProps.internalAndroidApplyInvertedFix + : convertRawProp( + context, + rawProps, + "internalAndroidApplyInvertedFix", + sourceProps.internalAndroidApplyInvertedFix, {})) {} void ScrollViewProps::setProp( @@ -368,6 +377,7 @@ void ScrollViewProps::setProp( RAW_SET_PROP_SWITCH_CASE_BASIC(snapToEnd); RAW_SET_PROP_SWITCH_CASE_BASIC(contentInsetAdjustmentBehavior); RAW_SET_PROP_SWITCH_CASE_BASIC(scrollToOverflowEnabled); + RAW_SET_PROP_SWITCH_CASE_BASIC(internalAndroidApplyInvertedFix); } } @@ -492,7 +502,11 @@ SharedDebugStringConvertibleList ScrollViewProps::getDebugProps() const { debugStringConvertibleItem( "snapToStart", snapToStart, defaultScrollViewProps.snapToStart), debugStringConvertibleItem( - "snapToEnd", snapToEnd, defaultScrollViewProps.snapToEnd)}; + "snapToEnd", snapToEnd, defaultScrollViewProps.snapToEnd), + debugStringConvertibleItem( + "internalAndroidApplyInvertedFix", + snapToEnd, + defaultScrollViewProps.internalAndroidApplyInvertedFix)}; } #endif diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h index dea44da3af5d..2c68787a60a1 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h @@ -68,6 +68,7 @@ class ScrollViewProps final : public ViewProps { ContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior{ ContentInsetAdjustmentBehavior::Never}; bool scrollToOverflowEnabled{false}; + bool internalAndroidApplyInvertedFix{false}; #pragma mark - DebugStringConvertible From f8ca759149b61312ba9d38796fcad99c3345cfa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 26 Jun 2023 20:20:27 +0200 Subject: [PATCH 2/4] Updated types and view config --- .../Libraries/Components/ScrollView/ScrollViewNativeComponent.js | 1 + .../Libraries/Components/ScrollView/ScrollViewViewConfig.js | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js index 2ba1886f4788..c1f219b18db0 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js @@ -86,6 +86,7 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = process: require('../../StyleSheet/processColor').default, }, pointerEvents: true, + internalAndroidApplyInvertedFix: true, }, } : { diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewViewConfig.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewViewConfig.js index 450b56657ec8..0bdda4325911 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewViewConfig.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewViewConfig.js @@ -78,6 +78,7 @@ const ScrollViewViewConfig = { snapToOffsets: true, snapToStart: true, zoomScale: true, + internalAndroidApplyInvertedFix: true, }, }; From 49af7f1de440f734ab764fa17785138e9394c4fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Tue, 27 Jun 2023 07:28:12 +0200 Subject: [PATCH 3/4] Add prop to ScrolLViewNativeComponentType --- .../Components/ScrollView/ScrollViewNativeComponentType.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js index b1b2df5d84e3..ec0e345d10ca 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js @@ -41,6 +41,7 @@ export type ScrollViewNativeProps = $ReadOnly<{ endFillColor?: ?ColorValue, fadingEdgeLength?: ?number, indicatorStyle?: ?('default' | 'black' | 'white'), + internalAndroidApplyInvertedFix?: ?boolean, keyboardDismissMode?: ?('none' | 'on-drag' | 'interactive'), maintainVisibleContentPosition?: ?$ReadOnly<{ minIndexForVisible: number, From 56f8381e6c9d0a2e6b2d171cdce7fd9d17a9a044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 3 Jul 2023 18:39:14 +0200 Subject: [PATCH 4/4] rename internalAndroidApplyInvertedFix -> isInvertedVirtualizedList --- .../ScrollView/ScrollViewNativeComponent.js | 2 +- .../ScrollView/ScrollViewNativeComponentType.js | 2 +- .../Components/ScrollView/ScrollViewViewConfig.js | 2 +- .../react/views/scroll/ReactScrollViewManager.java | 4 ++-- .../components/scrollview/ScrollViewProps.cpp | 14 +++++++------- .../components/scrollview/ScrollViewProps.h | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js index c1f219b18db0..69ebcef0d569 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js @@ -86,7 +86,7 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = process: require('../../StyleSheet/processColor').default, }, pointerEvents: true, - internalAndroidApplyInvertedFix: true, + isInvertedVirtualizedList: true, }, } : { diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js index ec0e345d10ca..f5a9632ee119 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js @@ -41,7 +41,7 @@ export type ScrollViewNativeProps = $ReadOnly<{ endFillColor?: ?ColorValue, fadingEdgeLength?: ?number, indicatorStyle?: ?('default' | 'black' | 'white'), - internalAndroidApplyInvertedFix?: ?boolean, + isInvertedVirtualizedList?: ?boolean, keyboardDismissMode?: ?('none' | 'on-drag' | 'interactive'), maintainVisibleContentPosition?: ?$ReadOnly<{ minIndexForVisible: number, diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewViewConfig.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewViewConfig.js index 0bdda4325911..55ba7b7abb0e 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewViewConfig.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewViewConfig.js @@ -46,6 +46,7 @@ const ScrollViewViewConfig = { fadingEdgeLength: true, indicatorStyle: true, inverted: true, + isInvertedVirtualizedList: true, keyboardDismissMode: true, maintainVisibleContentPosition: true, maximumZoomScale: true, @@ -78,7 +79,6 @@ const ScrollViewViewConfig = { snapToOffsets: true, snapToStart: true, zoomScale: true, - internalAndroidApplyInvertedFix: true, }, }; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java index 2f0d6c93ed7d..661443043897 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java @@ -380,8 +380,8 @@ public void setScrollEventThrottle(ReactScrollView view, int scrollEventThrottle view.setScrollEventThrottle(scrollEventThrottle); } - @ReactProp(name = "internalAndroidApplyInvertedFix") - public void setInternalAndroidApplyInvertedFix(ReactScrollView view, boolean applyFix) { + @ReactProp(name = "isInvertedVirtualizedList") + public void setIsInvertedVirtualizedList(ReactScrollView view, boolean applyFix) { // Usually when inverting the scroll view we are using scaleY: -1 on the list // and on the parent container. HOWEVER, starting from android API 33 there is // a bug that can cause an ANR due to that. Thus we are using different transform diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp index 03463afdfdbe..87c7a5c65742 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp @@ -320,14 +320,14 @@ ScrollViewProps::ScrollViewProps( "scrollToOverflowEnabled", sourceProps.scrollToOverflowEnabled, {})), - internalAndroidApplyInvertedFix( + isInvertedVirtualizedList( CoreFeatures::enablePropIteratorSetter - ? sourceProps.internalAndroidApplyInvertedFix + ? sourceProps.isInvertedVirtualizedList : convertRawProp( context, rawProps, - "internalAndroidApplyInvertedFix", - sourceProps.internalAndroidApplyInvertedFix, + "isInvertedVirtualizedList", + sourceProps.isInvertedVirtualizedList, {})) {} void ScrollViewProps::setProp( @@ -377,7 +377,7 @@ void ScrollViewProps::setProp( RAW_SET_PROP_SWITCH_CASE_BASIC(snapToEnd); RAW_SET_PROP_SWITCH_CASE_BASIC(contentInsetAdjustmentBehavior); RAW_SET_PROP_SWITCH_CASE_BASIC(scrollToOverflowEnabled); - RAW_SET_PROP_SWITCH_CASE_BASIC(internalAndroidApplyInvertedFix); + RAW_SET_PROP_SWITCH_CASE_BASIC(isInvertedVirtualizedList); } } @@ -504,9 +504,9 @@ SharedDebugStringConvertibleList ScrollViewProps::getDebugProps() const { debugStringConvertibleItem( "snapToEnd", snapToEnd, defaultScrollViewProps.snapToEnd), debugStringConvertibleItem( - "internalAndroidApplyInvertedFix", + "isInvertedVirtualizedList", snapToEnd, - defaultScrollViewProps.internalAndroidApplyInvertedFix)}; + defaultScrollViewProps.isInvertedVirtualizedList)}; } #endif diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h index 2c68787a60a1..72482e2002ec 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h @@ -68,7 +68,7 @@ class ScrollViewProps final : public ViewProps { ContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior{ ContentInsetAdjustmentBehavior::Never}; bool scrollToOverflowEnabled{false}; - bool internalAndroidApplyInvertedFix{false}; + bool isInvertedVirtualizedList{false}; #pragma mark - DebugStringConvertible