Is there a simple way to repeat a Android AnimatorSet
(infinite)? Can I set a AnimationListener
and restart the AnimatorSet
by calling
How about this?
@Override
public void onAnimationEnd(Animator animation) {
if (!mCanceled) {
animation.reset(); //<- added.
animation.start();
}
}
Set Infinite repeat count and restart / reverse repeat mode to all child animations
animatorSet.childAnimations.forEach {
val animator = it as ObjectAnimator
animator.repeatCount = ObjectAnimator.INFINITE
animator.repeatMode = ObjectAnimator.RESTART / REVERSE
}
There is an answer for the first two questions
Is there a simple way to repeat a Android AnimatorSet (infinite)? Can I set a AnimationListener and restart the animatorSet by calling start() again?
Yes, there is:
mAnimationSet.addListener(new AnimatorListenerAdapter() {
private boolean mCanceled;
@Override
public void onAnimationStart(Animator animation) {
mCanceled = false;
}
@Override
public void onAnimationCancel(Animator animation) {
mCanceled = true;
}
@Override
public void onAnimationEnd(Animator animation) {
if (!mCanceled) {
animation.start();
}
}
});
mAnimationSet.start();
The answer for the third question, is no. The first animation will be repeated and after all repetitions the succeeding animation will be started.
No, you can't repeat AnimatorSet, you can only repeat of a single ObjectAnimator/ ValueAnimator
But you can use PropertyValuesHolder, so that you can make an ObjectAnimator from a set of PropertyValuesHolder
here's example
val translateY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, -100f, 100f)
val alpha = PropertyValuesHolder.ofFloat(View.ALPHA, 0.3f, 0.7f)
val scaleX = PropertyValuesHolder.ofFloat(View.SCALE_X, 0.8f, 1.2f)
val scaleY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 0.8f, 1.2f)
// and more
ObjectAnimator.ofPropertyValuesHolder(myView, translateY, alpha, scaleX, scaleY).apply {
interpolator = AccelerateDecelerateInterpolator()
// duration of each animation
duration = 500L
// repeat infinite count (you can put n times)
repeatCount = ValueAnimator.INFINITE
// reverse animation after finish
repeatMode = ValueAnimator.REVERSE
// start animation
start()
}
Out of my head - animation framework is source of pain, especially if you want to support 2.x. I usually had problems with sets trying to do anythig more complexKeep track of with AnimationListener
kind-of "player". I keep track on which animation I play (like int
etc) and then on onAnimationEnd
I start another that should be in sequence. That way I can easily "script" my sequence, and do not bother broken framework.
So, none of the above options are appropriate.
If you use:
@Override
public void onAnimationEnd(Animator animation) {
if (!mCanceled) {
animation.start();
}
}
you will end up getting stackOverFlow exception sometimes.
The best thing is to do something like:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true && getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
set3.start();
}
});
SystemClock.sleep(1200);
}
}
});
t.start();