我有一个具有Instagram故事等功能的应用程序。我有5条以1乘1的条形填充以指示电影的长度。当视频再次开始播放时,这也可以正常工作,重设小节。
但是,当我切换到下一个视频并且与上一个视频一起位于bar3中时,bar0开始(如预期的那样),但是bar4也开始。切换到新视频会触发onAnimationEnd
,我希望取消动画,以便重新加载新的进度指示。 cancel()
,end()
,removeListener(this)
,它们都不起作用。
fun startAnimation(duration: Long, progressBars: ArrayList<ProgressBar>, currentBar: Int) {
Timber.d("test currentBar = $currentBar")
if (currentBar == 0) {
for (bar in progressBars) {
bar.setProgress(0)
}
}
animator?.end()
animator?.cancel()
animator?.removeAllListeners()
animator = null
animator = ValueAnimator.ofInt(0, progressBars[currentBar].getMax())
animator?.duration = duration
animator?.addUpdateListener { animation ->
progressBars[currentBar].setProgress(animation.animatedValue as Int)
}
animator?.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
// animation.removeListener(this)
animation.cancel()
animation.end()
var nextBar = currentBar + 1
if (nextBar == progressBars.size) {
nextBar = 0
}
Timber.d("test nextBar = $nextBar")
startAnimation(duration, progressBars, nextBar)
}
})
animator?.start()
}
最佳答案
第一件事是; cancel()
和end()
方法实际上是在调用onAnimationEnd()
方法。因此,在onAnimationEnd()
方法内部调用它们没有帮助。
您应该有一种停止已经开始的动画系列的方法。因为由于递归,它将继续开始下一个动画。
这是我们想要的代码(或更漂亮的东西);
lateinit currentViewBarAnimation: CancelableAnimation
fun onCreate(){
currentViewBarAnimation = startAnimation(duration, progressBars, 0)
}
fun onNextVideoStarted(){
currentViewBarAnimation.stopOrCancelOrWhateverYouNameIt()
currentViewBarAnimation = startAnimation(duration, progressBars, 0)
}
CancellableAnimation可以是仅具有 bool(boolean) 值的类。
class CancelableAnimation(private var cancelled: Boolean = false){
fun cancel(){
cancelled = true
}
fun isCancelled() = cancelled
}
现在是最后的接触;
fun startAnimation(duration: Long, progressBars: ArrayList<ProgressBar>, currentBar: Int) : CancellableAnimation{
Timber.d("test currentBar = $currentBar")
if (currentBar == 0) {
for (bar in progressBars) {
bar.setProgress(0)
}
}
animator?.end()
animator?.cancel()
animator?.removeAllListeners()
animator = ValueAnimator.ofInt(0, progressBars[currentBar].getMax())
animator?.duration = duration
animator?.addUpdateListener { animation ->
progressBars[currentBar].setProgress(animation.animatedValue as Int)
}
val cancellableAnimation = CancellableAnimation()
animator?.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
if(cancellableAnimation.isCancelled()) return
var nextBar = currentBar + 1
if (nextBar == progressBars.size) {
nextBar = 0
}
Timber.d("test nextBar = $nextBar")
startAnimation(duration, progressBars, nextBar)
}
})
animator?.start()
return cancellableAnimation
}
看起来有些混乱,但这是必须采取的措施,因为移至新视频是一种异步操作。