Skip to content

Commit 0601868

Browse files
yungstersfacebook-github-bot
authored andcommitted
Animated: Trigger Callback on Stopping Native Loops
Summary: Currently, `callback` in `Animated.loop(animation).start(callback)` does not get triggered when calling `stop()` if `animation` uses native driver. This diff implements that functionality. Changelog: [General][Changed] - Stopping an `Animated.loop` for a native animation will now correctly trigger completion callbacks supplied to `start()`. Differential Revision: D77329013
1 parent 6b85c54 commit 0601868

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

packages/react-native/Libraries/Animated/AnimatedImplementation.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export type CompositeAnimation = {
4242
start: (callback?: ?EndCallback, isLooping?: boolean) => void,
4343
stop: () => void,
4444
reset: () => void,
45-
_startNativeLoop: (iterations?: number) => void,
45+
_startNativeLoop(iterations: number, callback: ?EndCallback): void,
4646
_isUsingNativeDriver: () => boolean,
4747
...
4848
};
@@ -192,9 +192,9 @@ const springImpl = function (
192192
value.resetAnimation();
193193
},
194194

195-
_startNativeLoop: function (iterations?: number): void {
195+
_startNativeLoop(iterations: number, callback: ?EndCallback): void {
196196
const singleConfig = {...config, iterations};
197-
start(value, singleConfig);
197+
start(value, singleConfig, callback);
198198
},
199199

200200
_isUsingNativeDriver: function (): boolean {
@@ -246,9 +246,9 @@ const timingImpl = function (
246246
value.resetAnimation();
247247
},
248248

249-
_startNativeLoop: function (iterations?: number): void {
249+
_startNativeLoop(iterations: number, callback: ?EndCallback): void {
250250
const singleConfig = {...config, iterations};
251-
start(value, singleConfig);
251+
start(value, singleConfig, callback);
252252
},
253253

254254
_isUsingNativeDriver: function (): boolean {
@@ -288,9 +288,9 @@ const decayImpl = function (
288288
value.resetAnimation();
289289
},
290290

291-
_startNativeLoop: function (iterations?: number): void {
291+
_startNativeLoop(iterations: number, callback: ?EndCallback): void {
292292
const singleConfig = {...config, iterations};
293-
start(value, singleConfig);
293+
start(value, singleConfig, callback);
294294
},
295295

296296
_isUsingNativeDriver: function (): boolean {
@@ -484,7 +484,7 @@ const loopImpl = function (
484484
callback && callback({finished: true});
485485
} else {
486486
if (animation._isUsingNativeDriver()) {
487-
animation._startNativeLoop(iterations);
487+
animation._startNativeLoop(iterations, callback);
488488
} else {
489489
restart(); // Start looping recursively on the js thread
490490
}

packages/react-native/Libraries/Animated/__tests__/Animated-test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
* @format
99
*/
1010

11+
import type {EndCallback} from '../animations/Animation';
12+
1113
import * as React from 'react';
1214

1315
const {create, unmount, update} = require('../../../jest/renderer');
@@ -693,6 +695,31 @@ describe('Animated', () => {
693695
expect(animation.reset).toHaveBeenCalledTimes(1);
694696
expect(cb).toBeCalledWith({finished: false});
695697
});
698+
699+
it('stops looping native animations', () => {
700+
const value = new Animated.Value(0);
701+
const animation = Animated.timing(value, {
702+
toValue: 1,
703+
useNativeDriver: true,
704+
});
705+
706+
jest.spyOn(animation, '_startNativeLoop');
707+
jest.spyOn(animation, 'stop');
708+
709+
const callback = jest.fn();
710+
711+
const loop = Animated.loop(animation);
712+
loop.start(callback);
713+
714+
expect(animation._startNativeLoop).toBeCalledTimes(1);
715+
expect(animation.stop).not.toBeCalled();
716+
expect(callback).not.toBeCalled();
717+
718+
loop.stop();
719+
720+
expect(animation.stop).toBeCalled();
721+
expect(callback).toBeCalledWith({finished: false});
722+
});
696723
});
697724

698725
it('does not reset animation in a loop if resetBeforeIteration is false', () => {

0 commit comments

Comments
 (0)