animation = new Animated.Value(0);
animationSequnce = Animated.sequence(
[Animated.timing(this.animation, { toValue: 1 }),
Animated.timing(this.animation, { toValue: 0, delay: 1000 }),
],
);
startAnimation = () => {
animationSequnce.start();
}
stopAnimation = () => {
animationSequnce.stop();
}
我想多次启动animation sequence
。
我通过编写在按下按钮时调用startAnimation
的代码进行了测试。
动画在第一次运行时运行。
在第一个动画完成后单击第二个按钮时
发生Cannot read property 'start' of undefined
错误。
startAnimation = () => {
Animated.sequence(
[Animated.timing(this.animation, { toValue: 1 }),
Animated.timing(this.animation, { toValue: 0, delay: 1000 }),
],
).start();
}
对此startAnimation
所做的更改不会导致错误,但是您将无法调用stopAnimation
,因为它将每次都调用不同的AnimationSequnce
。
多次使用动画的最佳方法是什么?
答案 0 :(得分:0)
停止动画
this.animation.stopAnimation()
可选动画停止播放时获取回叫
this.animation.stopAnimation(this.callback())
或
Animated.timing(
this.animation
).stop();
答案 1 :(得分:0)
第一次调用 Animated.sequence()
时,react native 创建一个变量 current
,引用当前执行动画的索引,并存储在本地。
当 Animated.sequence().start()
完成后,变量 current
不会被清除或重置为 0,因此您第二次在同一个序列动画上调用 start()
时,数组索引超出绑定并导致错误。
这是react native的一个隐藏bug,下面是Animated.sequence
const sequence = function(
animations: Array<CompositeAnimation>,
): CompositeAnimation {
let current = 0;
return {
start: function(callback?: ?EndCallback) {
const onComplete = function(result) {
if (!result.finished) {
callback && callback(result);
return;
}
current++;
if (current === animations.length) {
callback && callback(result);
return;
}
animations[current].start(onComplete);
};
if (animations.length === 0) {
callback && callback({finished: true});
} else {
animations[current].start(onComplete);
}
},
stop: function() {
if (current < animations.length) {
animations[current].stop();
}
},
reset: function() {
animations.forEach((animation, idx) => {
if (idx <= current) {
animation.reset();
}
});
current = 0;
},
_startNativeLoop: function() {
throw new Error(
'Loops run using the native driver cannot contain Animated.sequence animations',
);
},
_isUsingNativeDriver: function(): boolean {
return false;
},
};
};
我的解决方案是定义一个自定义序列,并在序列动画完成后手动将 current
重置为 0:
const sequence = function(
animations: Array<CompositeAnimation>,
): CompositeAnimation {
let current = 0;
return {
start: function(callback?: ?EndCallback) {
const onComplete = function(result) {
if (!result.finished) {
current = 0;
callback && callback(result);
return;
}
current++;
if (current === animations.length) {
current = 0;
callback && callback(result);
return;
}
animations[current].start(onComplete);
};
if (animations.length === 0) {
current = 0;
callback && callback({finished: true});
} else {
animations[current].start(onComplete);
}
},
stop: function() {
if (current < animations.length) {
animations[current].stop();
}
},
reset: function() {
animations.forEach((animation, idx) => {
if (idx <= current) {
animation.reset();
}
});
current = 0;
},
_startNativeLoop: function() {
throw new Error(
'Loops run using the native driver cannot contain Animated.sequence animations',
);
},
_isUsingNativeDriver: function(): boolean {
return false;
},
};
};