diff --git a/Libraries/Animated/src/AnimatedImplementation.js b/Libraries/Animated/src/AnimatedImplementation.js index 55d7423998a299..f5fe1e94930281 100644 --- a/Libraries/Animated/src/AnimatedImplementation.js +++ b/Libraries/Animated/src/AnimatedImplementation.js @@ -725,7 +725,7 @@ class AnimatedValue extends AnimatedWithChildren { _startListeningToNativeValueUpdates() { if (this.__nativeAnimatedValueListener || - !NativeAnimatedHelper.supportNativeListener()) { + !NativeAnimatedHelper.supportsNativeListener()) { return; } @@ -740,7 +740,7 @@ class AnimatedValue extends AnimatedWithChildren { _stopListeningForNativeValueUpdates() { if (!this.__nativeAnimatedValueListener || - !NativeAnimatedHelper.supportNativeListener()) { + !NativeAnimatedHelper.supportsNativeListener()) { return; } diff --git a/Libraries/Animated/src/NativeAnimatedHelper.js b/Libraries/Animated/src/NativeAnimatedHelper.js index 809341dcbca54f..aefd32688fc9b1 100644 --- a/Libraries/Animated/src/NativeAnimatedHelper.js +++ b/Libraries/Animated/src/NativeAnimatedHelper.js @@ -148,7 +148,7 @@ function assertNativeAnimatedModule(): void { } // TODO: remove this when iOS supports native listeners. -function supportNativeListener(): bool { +function supportsNativeListener(): bool { return !!NativeAnimatedModule.startListeningToAnimatedNodeValue; } @@ -161,5 +161,5 @@ module.exports = { generateNewNodeTag, generateNewAnimationId, assertNativeAnimatedModule, - supportNativeListener, + supportsNativeListener, }; diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/AnimatedNodeValueListener.java b/ReactAndroid/src/main/java/com/facebook/react/animated/AnimatedNodeValueListener.java index a1047385607d33..fa0248cb3e1947 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/animated/AnimatedNodeValueListener.java +++ b/ReactAndroid/src/main/java/com/facebook/react/animated/AnimatedNodeValueListener.java @@ -12,6 +12,6 @@ /** * Interface used to listen to {@link ValueAnimatedNode} updates. */ -/* package */ interface AnimatedNodeValueListener { +public interface AnimatedNodeValueListener { void onValueUpdate(double value); } diff --git a/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java b/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java index 5f1a63f2730046..e321a0b6e8073a 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java @@ -140,6 +140,64 @@ public void testFramesAnimation() { verifyNoMoreInteractions(mUIImplementationMock); } + @Test + public void testNodeValueListenerIfNotListening() { + int nodeId = 1; + + createSimpleAnimatedViewWithOpacity(1000, 0d); + JavaOnlyArray frames = JavaOnlyArray.of(0d, 0.2d, 0.4d, 0.6d, 0.8d, 1d); + + Callback animationCallback = mock(Callback.class); + AnimatedNodeValueListener valueListener = mock(AnimatedNodeValueListener.class); + + mNativeAnimatedNodesManager.startListeningToAnimatedNodeValue(nodeId, valueListener); + mNativeAnimatedNodesManager.startAnimatingNode( + 1, + nodeId, + JavaOnlyMap.of("type", "frames", "frames", frames, "toValue", 1d), + animationCallback); + + mNativeAnimatedNodesManager.runUpdates(nextFrameTime()); + verify(valueListener).onValueUpdate(eq(0d)); + + mNativeAnimatedNodesManager.stopListeningToAnimatedNodeValue(nodeId); + + reset(valueListener); + mNativeAnimatedNodesManager.runUpdates(nextFrameTime()); + verifyNoMoreInteractions(valueListener); + } + + @Test + public void testNodeValueListenerIfListening() { + int nodeId = 1; + + createSimpleAnimatedViewWithOpacity(1000, 0d); + JavaOnlyArray frames = JavaOnlyArray.of(0d, 0.2d, 0.4d, 0.6d, 0.8d, 1d); + + Callback animationCallback = mock(Callback.class); + AnimatedNodeValueListener valueListener = mock(AnimatedNodeValueListener.class); + + mNativeAnimatedNodesManager.startListeningToAnimatedNodeValue(nodeId, valueListener); + mNativeAnimatedNodesManager.startAnimatingNode( + 1, + nodeId, + JavaOnlyMap.of("type", "frames", "frames", frames, "toValue", 1d), + animationCallback); + + mNativeAnimatedNodesManager.runUpdates(nextFrameTime()); + verify(valueListener).onValueUpdate(eq(0d)); + + for (int i = 0; i < frames.size(); i++) { + reset(valueListener); + mNativeAnimatedNodesManager.runUpdates(nextFrameTime()); + verify(valueListener).onValueUpdate(eq(frames.getDouble(i))); + } + + reset(valueListener); + mNativeAnimatedNodesManager.runUpdates(nextFrameTime()); + verifyNoMoreInteractions(valueListener); + } + @Test public void testAnimationCallbackFinish() { createSimpleAnimatedViewWithOpacity(1000, 0d);