如何使用顺序添加的动画重复 AnimationSet
How to repeat an AnimationSet with sequentially added animations
我正在尝试在我的 Activity
中制作动画以无限次重复。我已经在具有 repeatCount
和 repeatMode
属性的 XML 文件中尝试过它,但它不起作用。问题是 myanimation.xml
文件是由一组不同的动画构成的。
我的 XML 动画文件
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:interpolator="@android:anim/bounce_interpolator"
>
<translate
android:startOffset="1000"
android:fillAfter="true"
android:fromXDelta="10"
android:fromYDelta="10"
android:toXDelta="50"
android:toYDelta="-200"
android:duration="1800"
android:interpolator="@android:anim/bounce_interpolator"
/>
<translate
android:fillAfter="true"
android:startOffset="2000"
android:fromYDelta="10"
android:fromXDelta="10"
android:toXDelta="100"
android:toYDelta="270"
android:duration="1800"
android:interpolator="@android:anim/bounce_interpolator" />
<translate
android:fillAfter="true"
android:startOffset="3000"
android:fromYDelta="10"
android:fromXDelta="10"
android:toXDelta="130"
android:toYDelta="-270"
android:duration="1800"
android:interpolator="@android:anim/bounce_interpolator"
/>
<translate
android:fillAfter="true"
android:startOffset="4000"
android:fromYDelta="10"
android:fromXDelta="10"
android:toXDelta="140"
android:toYDelta="270"
android:duration="1800"
android:interpolator="@android:anim/bounce_interpolator"
/>
<translate
android:fillAfter="true"
android:startOffset="5000"
android:fromYDelta="10"
android:fromXDelta="10"
android:toXDelta="90"
android:toYDelta="-270"
android:duration="1800"
android:interpolator="@android:anim/bounce_interpolator"
/>
在 onCreate()
中,我将动画绑定到 ImageView
对象。
ImageView ball = (ImageView) findViewById(R.id.animationBall);
final Animation myAnimation = AnimationUtils.loadAnimation(this, R.anim.ball_animation);
ball.startAnimation(myAnimation);
动画效果很好,唯一的问题是它不想自己重复,即使我设置了 setRepeatMode()
或 setRepeatCount()
方法。
就其价值而言,setRepeatMode()
和 setRepeatCount()
必须设置在 Animation
对象上,而不是 AnimationSet
对象上。这可能是您犯的一个错误。
因此,要么在 Animation
对象上调用这些方法,要么将这些属性添加到 translate
架构的 XML 中。
另一种方法是设置无限重复的动画如下:
mAnimationSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mAnimationSet.start();
}
});
mAnimationSet.start();
Y.S 答案似乎还不错,但动画一直在播放,即使我希望它在某个时候被取消。所以我这样做了:
animations.playSequentially(
objectAnimator1,objectAnimator2)
animations.addListener(object: Animator.AnimatorListener{
var isCancelled = false
override fun onAnimationRepeat(animation: Animator?) {
}
override fun onAnimationCancel(animation: Animator?) {
isCancelled = true
}
override fun onAnimationStart(animation: Animator?) {
}
override fun onAnimationEnd(animation: Animator?) {
if(isCancelled.not()) animations.start()
}
})
animations.start()
更新:发现 ktx 有一些 extension functions:我们可以删除样板重载并使用它:
inline fun Animator.addListener(
crossinline onEnd: (animator: Animator) -> Unit = {},
crossinline onStart: (animator: Animator) -> Unit = {},
crossinline onCancel: (animator: Animator) -> Unit = {},
crossinline onRepeat: (animator: Animator) -> Unit = {})
所以这意味着如果你只想调用 onEnd,你可以做这样的事情:
animations.addListener(onEnd = {animations.start() //loop forever })
而不是取消,只需使用 animations.pause 和 animations.resume。
我正在尝试在我的 Activity
中制作动画以无限次重复。我已经在具有 repeatCount
和 repeatMode
属性的 XML 文件中尝试过它,但它不起作用。问题是 myanimation.xml
文件是由一组不同的动画构成的。
我的 XML 动画文件
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:interpolator="@android:anim/bounce_interpolator"
>
<translate
android:startOffset="1000"
android:fillAfter="true"
android:fromXDelta="10"
android:fromYDelta="10"
android:toXDelta="50"
android:toYDelta="-200"
android:duration="1800"
android:interpolator="@android:anim/bounce_interpolator"
/>
<translate
android:fillAfter="true"
android:startOffset="2000"
android:fromYDelta="10"
android:fromXDelta="10"
android:toXDelta="100"
android:toYDelta="270"
android:duration="1800"
android:interpolator="@android:anim/bounce_interpolator" />
<translate
android:fillAfter="true"
android:startOffset="3000"
android:fromYDelta="10"
android:fromXDelta="10"
android:toXDelta="130"
android:toYDelta="-270"
android:duration="1800"
android:interpolator="@android:anim/bounce_interpolator"
/>
<translate
android:fillAfter="true"
android:startOffset="4000"
android:fromYDelta="10"
android:fromXDelta="10"
android:toXDelta="140"
android:toYDelta="270"
android:duration="1800"
android:interpolator="@android:anim/bounce_interpolator"
/>
<translate
android:fillAfter="true"
android:startOffset="5000"
android:fromYDelta="10"
android:fromXDelta="10"
android:toXDelta="90"
android:toYDelta="-270"
android:duration="1800"
android:interpolator="@android:anim/bounce_interpolator"
/>
在 onCreate()
中,我将动画绑定到 ImageView
对象。
ImageView ball = (ImageView) findViewById(R.id.animationBall);
final Animation myAnimation = AnimationUtils.loadAnimation(this, R.anim.ball_animation);
ball.startAnimation(myAnimation);
动画效果很好,唯一的问题是它不想自己重复,即使我设置了 setRepeatMode()
或 setRepeatCount()
方法。
就其价值而言,setRepeatMode()
和 setRepeatCount()
必须设置在 Animation
对象上,而不是 AnimationSet
对象上。这可能是您犯的一个错误。
因此,要么在 Animation
对象上调用这些方法,要么将这些属性添加到 translate
架构的 XML 中。
另一种方法是设置无限重复的动画如下:
mAnimationSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mAnimationSet.start();
}
});
mAnimationSet.start();
Y.S 答案似乎还不错,但动画一直在播放,即使我希望它在某个时候被取消。所以我这样做了:
animations.playSequentially(
objectAnimator1,objectAnimator2)
animations.addListener(object: Animator.AnimatorListener{
var isCancelled = false
override fun onAnimationRepeat(animation: Animator?) {
}
override fun onAnimationCancel(animation: Animator?) {
isCancelled = true
}
override fun onAnimationStart(animation: Animator?) {
}
override fun onAnimationEnd(animation: Animator?) {
if(isCancelled.not()) animations.start()
}
})
animations.start()
更新:发现 ktx 有一些 extension functions:我们可以删除样板重载并使用它:
inline fun Animator.addListener(
crossinline onEnd: (animator: Animator) -> Unit = {},
crossinline onStart: (animator: Animator) -> Unit = {},
crossinline onCancel: (animator: Animator) -> Unit = {},
crossinline onRepeat: (animator: Animator) -> Unit = {})
所以这意味着如果你只想调用 onEnd,你可以做这样的事情:
animations.addListener(onEnd = {animations.start() //loop forever })
而不是取消,只需使用 animations.pause 和 animations.resume。