mirror of
https://github.com/facebook/react-native.git
synced 2024-11-21 22:10:14 +00:00
Dispatch onMomentumScrollEnd after programmatic scrolling (#45187)
Summary: in iOS on a scroll generated programatically, the `onMomentScrollEnd` is fired, though in case of android the same does not happen, this PR tries to implement the same behaviour for android as well, while diving through the code it seems we have two extra `onMomentumScrollEnd` events. Only one event should be fired. **iOS Behaviour on Programmatic Scroll** https://github.com/facebook/react-native/assets/72331432/fb8f16b1-4db6-49fe-83a1-a1c40bf49705 https://github.com/facebook/react-native/assets/72331432/9842f522-b616-4fb3-b197-40817f4aa9cb **Android Behaviour on Programmatic Scroll** https://github.com/facebook/react-native/assets/72331432/c24d3f06-4e2a-4bef-81af-d9227a3b1a4a https://github.com/facebook/react-native/assets/72331432/d4917843-730b-4bd7-90d9-33efb0f471a7 If closely observed we can see the `onMomentumScrollEnd` does not gets called in Android unlike to iOS. ## Changelog: [Android][Fixed] - Dispatch onMomentumScrollEnd after programmatic scrolling Pull Request resolved: https://github.com/facebook/react-native/pull/45187 Test Plan: i have added updates to the FlatList example and ScrollViewSimple here is a ScreenRecording of `onMomentumScrollEnd` firing in android after the code changes https://github.com/facebook/react-native/assets/72331432/f036d1a5-6ebf-47ba-becd-4db98a406b15 https://github.com/facebook/react-native/assets/72331432/8c788c39-3392-4822-99c5-6e320398714b Reviewed By: javache Differential Revision: D65539724 Pulled By: Abbondanzo fbshipit-source-id: f3a5527ac5979f5ec0c6ae18d80fdc20c9c9c14b
This commit is contained in:
parent
6f59627903
commit
c69e330324
@ -6975,6 +6975,7 @@ public final class com/facebook/react/views/scroll/ReactScrollViewHelper {
|
||||
public static final field SNAP_ALIGNMENT_START I
|
||||
public static final fun addLayoutChangeListener (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$LayoutChangeListener;)V
|
||||
public static final fun addScrollListener (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ScrollListener;)V
|
||||
public static final fun dispatchMomentumEndOnAnimationEnd (Landroid/view/ViewGroup;)V
|
||||
public static final fun emitLayoutChangeEvent (Landroid/view/ViewGroup;)V
|
||||
public static final fun emitLayoutEvent (Landroid/view/ViewGroup;)V
|
||||
public static final fun emitScrollBeginDragEvent (Landroid/view/ViewGroup;)V
|
||||
|
@ -1516,12 +1516,20 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
|
||||
DEFAULT_FLING_ANIMATOR.cancel();
|
||||
|
||||
// Update the fling animator with new values
|
||||
DEFAULT_FLING_ANIMATOR
|
||||
.setDuration(ReactScrollViewHelper.getDefaultScrollAnimationDuration(getContext()))
|
||||
.setIntValues(start, end);
|
||||
int duration = ReactScrollViewHelper.getDefaultScrollAnimationDuration(getContext());
|
||||
DEFAULT_FLING_ANIMATOR.setDuration(duration).setIntValues(start, end);
|
||||
|
||||
// Start the animator
|
||||
DEFAULT_FLING_ANIMATOR.start();
|
||||
|
||||
if (mSendMomentumEvents) {
|
||||
int xVelocity = 0;
|
||||
if (duration > 0) {
|
||||
xVelocity = (end - start) / duration;
|
||||
}
|
||||
ReactScrollViewHelper.emitScrollMomentumBeginEvent(this, xVelocity, 0);
|
||||
ReactScrollViewHelper.dispatchMomentumEndOnAnimationEnd(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1329,12 +1329,20 @@ public class ReactScrollView extends ScrollView
|
||||
DEFAULT_FLING_ANIMATOR.cancel();
|
||||
|
||||
// Update the fling animator with new values
|
||||
DEFAULT_FLING_ANIMATOR
|
||||
.setDuration(ReactScrollViewHelper.getDefaultScrollAnimationDuration(getContext()))
|
||||
.setIntValues(start, end);
|
||||
int duration = ReactScrollViewHelper.getDefaultScrollAnimationDuration(getContext());
|
||||
DEFAULT_FLING_ANIMATOR.setDuration(duration).setIntValues(start, end);
|
||||
|
||||
// Start the animator
|
||||
DEFAULT_FLING_ANIMATOR.start();
|
||||
|
||||
if (mSendMomentumEvents) {
|
||||
int yVelocity = 0;
|
||||
if (duration > 0) {
|
||||
yVelocity = (end - start) / duration;
|
||||
}
|
||||
ReactScrollViewHelper.emitScrollMomentumBeginEvent(this, 0, yVelocity);
|
||||
ReactScrollViewHelper.dispatchMomentumEndOnAnimationEnd(this);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -409,6 +409,31 @@ public object ReactScrollViewHelper {
|
||||
})
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun <T> dispatchMomentumEndOnAnimationEnd(scrollView: T) where
|
||||
T : HasFlingAnimator?,
|
||||
T : HasScrollEventThrottle?,
|
||||
T : ViewGroup {
|
||||
scrollView
|
||||
.getFlingAnimator()
|
||||
.addListener(
|
||||
object : Animator.AnimatorListener {
|
||||
override fun onAnimationStart(animator: Animator) = Unit
|
||||
|
||||
override fun onAnimationEnd(animator: Animator) {
|
||||
emitScrollMomentumEndEvent(scrollView)
|
||||
animator.removeListener(this)
|
||||
}
|
||||
|
||||
override fun onAnimationCancel(animator: Animator) {
|
||||
emitScrollMomentumEndEvent(scrollView)
|
||||
animator.removeListener(this)
|
||||
}
|
||||
|
||||
override fun onAnimationRepeat(animator: Animator) = Unit
|
||||
})
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun <T> predictFinalScrollPosition(
|
||||
scrollView: T,
|
||||
|
Loading…
Reference in New Issue
Block a user