Skip to content

Commit aa85da3

Browse files
Nick Lefevermeta-codesync[bot]
authored andcommitted
Support loading and assigning scroll state from scroll view helper (#53999)
Summary: Pull Request resolved: #53999 Update the `ScrollViewHelper` class to support reading the scroll state from the provided `stateWrapper` and assigning it to the view implementing the `HasScrollState` interface. This will be used in a future diff to implement scroll state loading on the scroll view component in the scroll state setter function. This enables having one implementation of the state loading for all variants of the scroll view (vertical and horizontal scroll views). Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D83247018 fbshipit-source-id: 44f10edab2341981b85d6ab8b83c7bea96c1e09d
1 parent aa492fa commit aa85da3

File tree

4 files changed

+74
-16
lines changed

4 files changed

+74
-16
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5636,6 +5636,7 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollView : android
56365636
public fun setOverflowInset (IIII)V
56375637
public fun setPagingEnabled (Z)V
56385638
public fun setPointerEvents (Lcom/facebook/react/uimanager/PointerEvents;)V
5639+
public fun setReactScrollViewScrollState (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState;)V
56395640
public fun setRemoveClippedSubviews (Z)V
56405641
public fun setScrollEnabled (Z)V
56415642
public fun setScrollEventThrottle (I)V
@@ -5775,6 +5776,7 @@ public class com/facebook/react/views/scroll/ReactScrollView : android/widget/Sc
57755776
public fun setOverflowInset (IIII)V
57765777
public fun setPagingEnabled (Z)V
57775778
public fun setPointerEvents (Lcom/facebook/react/uimanager/PointerEvents;)V
5779+
public fun setReactScrollViewScrollState (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState;)V
57785780
public fun setRemoveClippedSubviews (Z)V
57795781
public fun setScrollAwayTopPaddingEnabledUnstable (I)V
57805782
public fun setScrollEnabled (Z)V
@@ -5879,6 +5881,7 @@ public abstract interface class com/facebook/react/views/scroll/ReactScrollViewH
58795881

58805882
public abstract interface class com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollState {
58815883
public abstract fun getReactScrollViewScrollState ()Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState;
5884+
public abstract fun setReactScrollViewScrollState (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState;)V
58825885
}
58835886

58845887
public abstract interface class com/facebook/react/views/scroll/ReactScrollViewHelper$HasSmoothScroll {
@@ -5896,18 +5899,34 @@ public abstract interface class com/facebook/react/views/scroll/ReactScrollViewH
58965899

58975900
public final class com/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState {
58985901
public fun <init> ()V
5902+
public fun <init> (Landroid/graphics/Point;ILandroid/graphics/Point;ZZFZ)V
5903+
public synthetic fun <init> (Landroid/graphics/Point;ILandroid/graphics/Point;ZZFZILkotlin/jvm/internal/DefaultConstructorMarker;)V
5904+
public final fun component1 ()Landroid/graphics/Point;
5905+
public final fun component2 ()I
5906+
public final fun component3 ()Landroid/graphics/Point;
5907+
public final fun component4 ()Z
5908+
public final fun component5 ()Z
5909+
public final fun component6 ()F
5910+
public final fun component7 ()Z
5911+
public final fun copy (Landroid/graphics/Point;ILandroid/graphics/Point;ZZFZ)Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState;
5912+
public static synthetic fun copy$default (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState;Landroid/graphics/Point;ILandroid/graphics/Point;ZZFZILjava/lang/Object;)Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState;
5913+
public fun equals (Ljava/lang/Object;)Z
58995914
public final fun getDecelerationRate ()F
59005915
public final fun getFinalAnimatedPositionScroll ()Landroid/graphics/Point;
59015916
public final fun getLastStateUpdateScroll ()Landroid/graphics/Point;
59025917
public final fun getScrollAwayPaddingTop ()I
5918+
public fun hashCode ()I
59035919
public final fun isCanceled ()Z
59045920
public final fun isFinished ()Z
5921+
public final fun isUpdatedByScroll ()Z
59055922
public final fun setCanceled (Z)V
59065923
public final fun setDecelerationRate (F)V
59075924
public final fun setFinalAnimatedPositionScroll (II)Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState;
59085925
public final fun setFinished (Z)V
59095926
public final fun setLastStateUpdateScroll (II)Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState;
59105927
public final fun setScrollAwayPaddingTop (I)V
5928+
public final fun setUpdatedByScroll (Z)V
5929+
public fun toString ()Ljava/lang/String;
59115930
}
59125931

59135932
public abstract interface class com/facebook/react/views/scroll/ReactScrollViewHelper$ScrollListener {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,11 @@ public void setStateWrapper(StateWrapper stateWrapper) {
16491649
mStateWrapper = stateWrapper;
16501650
}
16511651

1652+
@Override
1653+
public void setReactScrollViewScrollState(ReactScrollViewScrollState scrollState) {
1654+
mReactScrollViewScrollState = scrollState;
1655+
}
1656+
16521657
@Override
16531658
public ReactScrollViewScrollState getReactScrollViewScrollState() {
16541659
return mReactScrollViewScrollState;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,11 @@ private void updateScrollAwayState(int scrollAwayPaddingTop) {
14671467
ReactScrollViewHelper.forceUpdateState(this);
14681468
}
14691469

1470+
@Override
1471+
public void setReactScrollViewScrollState(ReactScrollViewScrollState scrollState) {
1472+
mReactScrollViewScrollState = scrollState;
1473+
}
1474+
14701475
@Override
14711476
public ReactScrollViewScrollState getReactScrollViewScrollState() {
14721477
return mReactScrollViewScrollState;

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

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import com.facebook.react.bridge.WritableNativeMap
2626
import com.facebook.react.common.ReactConstants
2727
import com.facebook.react.fabric.FabricUIManager
2828
import com.facebook.react.uimanager.PixelUtil.toDIPFromPixel
29+
import com.facebook.react.uimanager.PixelUtil.toPixelFromDIP
2930
import com.facebook.react.uimanager.ReactClippingViewGroup
3031
import com.facebook.react.uimanager.StateWrapper
3132
import com.facebook.react.uimanager.UIManagerHelper
@@ -361,6 +362,10 @@ public object ReactScrollViewHelper {
361362
return
362363
}
363364
val scrollState = scrollView.reactScrollViewScrollState
365+
366+
// User driven scrolling should disable scroll state updates coming from Fabric
367+
scrollState.isUpdatedByScroll = true
368+
364369
// Dedupe events to reduce JNI traffic
365370
if (scrollState.lastStateUpdateScroll.equals(scrollX, scrollY)) {
366371
return
@@ -399,6 +404,29 @@ public object ReactScrollViewHelper {
399404
}
400405
}
401406

407+
@JvmStatic
408+
internal fun <T> loadFabricScrollState(scrollView: T, stateWrapper: StateWrapper)
409+
where T : HasScrollState?, T : HasStateWrapper?, T : ViewGroup {
410+
if (scrollView.reactScrollViewScrollState.isUpdatedByScroll) {
411+
return
412+
}
413+
414+
val stateData = stateWrapper.stateData
415+
if (stateData == null) {
416+
return
417+
}
418+
419+
// Assign the data loaded from the shadow node state
420+
val scrollX = toPixelFromDIP(stateData.getDouble(CONTENT_OFFSET_LEFT)).toInt()
421+
val scrollY = toPixelFromDIP(stateData.getDouble(CONTENT_OFFSET_TOP)).toInt()
422+
val scrollAwayPaddingTop = toPixelFromDIP(stateData.getDouble(SCROLL_AWAY_PADDING_TOP)).toInt()
423+
424+
val scrollState =
425+
scrollView.reactScrollViewScrollState.copy(scrollAwayPaddingTop = scrollAwayPaddingTop)
426+
scrollState.setLastStateUpdateScroll(scrollX, scrollY)
427+
scrollView.reactScrollViewScrollState = scrollState
428+
}
429+
402430
@JvmStatic
403431
public fun <T> updateStateOnScrollChanged(scrollView: T, xVelocity: Float, yVelocity: Float)
404432
where
@@ -596,21 +624,22 @@ public object ReactScrollViewHelper {
596624
}
597625
}
598626

599-
public class ReactScrollViewScrollState {
600-
601-
/** Get the position after current animation is finished */
602-
public val finalAnimatedPositionScroll: Point = Point()
603-
/** Get the padding on the top for nav bar */
604-
public var scrollAwayPaddingTop: Int = 0
605-
/** Get the Fabric state of last scroll position */
606-
public val lastStateUpdateScroll: Point = Point(-1, -1)
607-
/** Get true if the previous animation was canceled */
608-
public var isCanceled: Boolean = false
609-
/** Get true if previous animation was finished */
610-
public var isFinished: Boolean = true
611-
/** Get true if previous animation was finished */
612-
public var decelerationRate: Float = 0.985f
613-
627+
public data class ReactScrollViewScrollState(
628+
/** Get the position after current animation is finished */
629+
val finalAnimatedPositionScroll: Point = Point(),
630+
/** Get the padding on the top for nav bar */
631+
var scrollAwayPaddingTop: Int = 0,
632+
/** Get the Fabric state of last scroll position */
633+
val lastStateUpdateScroll: Point = Point(-1, -1),
634+
/** Get true if the previous animation was canceled */
635+
var isCanceled: Boolean = false,
636+
/** Get true if previous animation was finished */
637+
var isFinished: Boolean = true,
638+
/** Get true if previous animation was finished */
639+
var decelerationRate: Float = 0.985f,
640+
/** Get true if the component submitted the state through user scrolling */
641+
var isUpdatedByScroll: Boolean = false,
642+
) {
614643
/** Set the final scroll position after scrolling animation is finished */
615644
public fun setFinalAnimatedPositionScroll(
616645
finalAnimatedPositionScrollX: Int,
@@ -632,7 +661,7 @@ public object ReactScrollViewHelper {
632661

633662
public interface HasScrollState {
634663
/** Get the scroll state for the current ScrollView */
635-
public val reactScrollViewScrollState: ReactScrollViewScrollState
664+
public var reactScrollViewScrollState: ReactScrollViewScrollState
636665
}
637666

638667
public interface HasFlingAnimator {

0 commit comments

Comments
 (0)