Stop native driver animations when value is set.
Summary:
This diff changes the behaviour of natively driven animations in case the node that they are being run for has its value changed using `setValue` or as a result of an incoming event.
The reason for changing that is to match the JS implementation of `setValue` which behaves as described above (see relevant code here: 7cdd4d48c8/Libraries/Animated/src/AnimatedImplementation.js (L743)
)
**Test Plan:**
Use this sample app: https://snack.expo.io/B1V7RX9r-
Change: `USE_NATIVE_DRIVER` const between `true` and `false`.
See the animation stops regardless of the state of `USE_NATIVE_DRIVER` unlike before when it would stop only when `USE_NATIVE_DRIVER` was set to `false`
Closes https://github.com/facebook/react-native/pull/15054
Differential Revision: D5463750
Pulled By: hramos
fbshipit-source-id: e164c5299588ba8cac2937260c9ba9f6053b04e5
This commit is contained in:
parent
2334899dfe
commit
b8fafb46c1
|
@ -170,6 +170,7 @@
|
|||
RCTLogError(@"Not a value node.");
|
||||
return;
|
||||
}
|
||||
[self stopAnimationsForNode:node];
|
||||
|
||||
RCTValueAnimatedNode *valueNode = (RCTValueAnimatedNode *)node;
|
||||
valueNode.value = value.floatValue;
|
||||
|
@ -264,6 +265,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)stopAnimationsForNode:(nonnull RCTAnimatedNode *)node
|
||||
{
|
||||
NSMutableArray<id<RCTAnimationDriver>> *discarded = [NSMutableArray new];
|
||||
for (id<RCTAnimationDriver> driver in _activeAnimations) {
|
||||
if ([driver.valueNode isEqual:node]) {
|
||||
[discarded addObject:driver];
|
||||
}
|
||||
}
|
||||
for (id<RCTAnimationDriver> driver in discarded) {
|
||||
[driver stopAnimation];
|
||||
[_activeAnimations removeObject:driver];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -- Events
|
||||
|
||||
- (void)addAnimatedEventToView:(nonnull NSNumber *)viewTag
|
||||
|
@ -328,6 +343,7 @@
|
|||
NSMutableArray<RCTEventAnimation *> *driversForKey = _eventDrivers[key];
|
||||
if (driversForKey) {
|
||||
for (RCTEventAnimation *driver in driversForKey) {
|
||||
[self stopAnimationsForNode:driver.valueNode];
|
||||
[driver updateWithEvent:event];
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ import com.facebook.react.uimanager.events.EventDispatcherListener;
|
|||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -145,6 +144,7 @@ import javax.annotation.Nullable;
|
|||
throw new JSApplicationIllegalArgumentException("Animated node with tag " + tag +
|
||||
" does not exists or is not a 'value' node");
|
||||
}
|
||||
stopAnimationsForNode(node);
|
||||
((ValueAnimatedNode) node).mValue = value;
|
||||
mUpdatedNodes.put(tag, node);
|
||||
}
|
||||
|
@ -208,6 +208,24 @@ import javax.annotation.Nullable;
|
|||
mActiveAnimations.put(animationId, animation);
|
||||
}
|
||||
|
||||
private void stopAnimationsForNode(AnimatedNode animatedNode) {
|
||||
// in most of the cases there should never be more than a few active animations running at the
|
||||
// same time. Therefore it does not make much sense to create an animationId -> animation
|
||||
// object map that would require additional memory just to support the use-case of stopping
|
||||
// an animation
|
||||
for (int i = 0; i < mActiveAnimations.size(); i++) {
|
||||
AnimationDriver animation = mActiveAnimations.valueAt(i);
|
||||
if (animatedNode.equals(animation.mAnimatedValue)) {
|
||||
// Invoke animation end callback with {finished: false}
|
||||
WritableMap endCallbackResponse = Arguments.createMap();
|
||||
endCallbackResponse.putBoolean("finished", false);
|
||||
animation.mEndCallback.invoke(endCallbackResponse);
|
||||
mActiveAnimations.removeAt(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stopAnimation(int animationId) {
|
||||
// in most of the cases there should never be more than a few active animations running at the
|
||||
// same time. Therefore it does not make much sense to create an animationId -> animation
|
||||
|
@ -362,6 +380,7 @@ import javax.annotation.Nullable;
|
|||
List<EventAnimationDriver> driversForKey = mEventDrivers.get(event.getViewTag() + eventName);
|
||||
if (driversForKey != null) {
|
||||
for (EventAnimationDriver driver : driversForKey) {
|
||||
stopAnimationsForNode(driver.mValueNode);
|
||||
event.dispatch(driver);
|
||||
mRunUpdateNodeList.add(driver.mValueNode);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue