diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 8afeee79e05f..dd62d4cf3aa7 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6646,11 +6646,11 @@ public abstract interface class com/facebook/react/views/scroll/FpsListener { public abstract fun isEnabled ()Z } -public class com/facebook/react/views/scroll/OnScrollDispatchHelper { +public final class com/facebook/react/views/scroll/OnScrollDispatchHelper { public fun ()V - public fun getXFlingVelocity ()F - public fun getYFlingVelocity ()F - public fun onScrollChanged (II)Z + public final fun getXFlingVelocity ()F + public final fun getYFlingVelocity ()F + public final fun onScrollChanged (II)Z } public class com/facebook/react/views/scroll/ReactHorizontalScrollContainerView : com/facebook/react/views/view/ReactViewGroup { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/OnScrollDispatchHelper.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/OnScrollDispatchHelper.java deleted file mode 100644 index a7a659a3d42c..000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/OnScrollDispatchHelper.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.scroll; - -import android.os.SystemClock; -import com.facebook.infer.annotation.Nullsafe; - -/** - * Android has a bug where onScrollChanged is called twice per frame with the same params during - * flings. We hack around that here by trying to detect that duplicate call and not dispatch it. See - * https://code.google.com/p/android/issues/detail?id=39473 - */ -@Nullsafe(Nullsafe.Mode.LOCAL) -public class OnScrollDispatchHelper { - - private static final int MIN_EVENT_SEPARATION_MS = 10; - - private int mPrevX = Integer.MIN_VALUE; - private int mPrevY = Integer.MIN_VALUE; - private float mXFlingVelocity = 0; - private float mYFlingVelocity = 0; - - private long mLastScrollEventTimeMs = -(MIN_EVENT_SEPARATION_MS + 1); - - /** - * Call from a ScrollView in onScrollChanged, returns true if this onScrollChanged is legit (not a - * duplicate) and should be dispatched. - */ - public boolean onScrollChanged(int x, int y) { - long eventTime = SystemClock.uptimeMillis(); - boolean shouldDispatch = - eventTime - mLastScrollEventTimeMs > MIN_EVENT_SEPARATION_MS || mPrevX != x || mPrevY != y; - - if (eventTime - mLastScrollEventTimeMs != 0) { - mXFlingVelocity = (float) (x - mPrevX) / (eventTime - mLastScrollEventTimeMs); - mYFlingVelocity = (float) (y - mPrevY) / (eventTime - mLastScrollEventTimeMs); - } - - mLastScrollEventTimeMs = eventTime; - mPrevX = x; - mPrevY = y; - - return shouldDispatch; - } - - public float getXFlingVelocity() { - return mXFlingVelocity; - } - - public float getYFlingVelocity() { - return mYFlingVelocity; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/OnScrollDispatchHelper.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/OnScrollDispatchHelper.kt new file mode 100644 index 000000000000..42a0c2ca4acc --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/OnScrollDispatchHelper.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.views.scroll + +import android.os.SystemClock + +/** + * Android has a bug where onScrollChanged is called twice per frame with the same params during + * flings. We hack around that here by trying to detect that duplicate call and not dispatch it. See + * https://code.google.com/p/android/issues/detail?id=39473 + */ +public class OnScrollDispatchHelper { + + private var prevX = Int.MIN_VALUE + private var prevY = Int.MIN_VALUE + public var xFlingVelocity: Float = 0f + private set + + public var yFlingVelocity: Float = 0f + private set + + private var lastScrollEventTimeMs = -(MIN_EVENT_SEPARATION_MS + 1).toLong() + + /** + * Call from a ScrollView in onScrollChanged, returns true if this onScrollChanged is legit (not a + * duplicate) and should be dispatched. + */ + public fun onScrollChanged(x: Int, y: Int): Boolean { + val eventTime = SystemClock.uptimeMillis() + val shouldDispatch = + eventTime - lastScrollEventTimeMs > MIN_EVENT_SEPARATION_MS || prevX != x || prevY != y + if (eventTime - lastScrollEventTimeMs != 0L) { + xFlingVelocity = (x - prevX).toFloat() / (eventTime - lastScrollEventTimeMs) + yFlingVelocity = (y - prevY).toFloat() / (eventTime - lastScrollEventTimeMs) + } + lastScrollEventTimeMs = eventTime + prevX = x + prevY = y + return shouldDispatch + } + + private companion object { + private const val MIN_EVENT_SEPARATION_MS = 10 + } +}