Reputation: 5269
I have a question concerning ObjectAnimator in Android. I am trying to model a Bounce effect whereby the View slides up (decreasing Y value) and back down after by the same amount 'n', followed by the View sliding up and down again but this time by 'n/2' (so half the distance).
So a bigger bounce, followed by a shallower bounce - i.e., the kinda thing a Mac icon does in the tray when it wants your attention.
Here is what I've tried so far (assume v
is a View
):
float y = v.getTranslationY(),distance = 20F;
AnimatorSet s = new AnimatorSet();
s.play(ObjectAnimator.ofFloat(v, "translationY", y- distance).setDuration(500))
.before(ObjectAnimator.ofFloat(v, "translationY", y).setDuration(500))
.before(ObjectAnimator.ofFloat(v, "translationY", y- (distance/2)).setDuration(500))
.before(ObjectAnimator.ofFloat(v, "translationY", y).setDuration(500));
s.start();
Ignore the code quality, it's a POC! I was hoping this would work, but it seems to only 'bounce' once as if its combined the animations despite the use of .before()
.
Could you please show me how I can create complex AnimatorSet chains that do not amalgamate in to one, as I seem to be missing something?
BONUS: For extra points, how can I set the repeat of an AnimatorSet?
Many thanks!
Upvotes: 9
Views: 22260
Reputation: 45140
If you are using Kotlin
do it like this:
val animationSet = AnimatorSet();
animationSet.playSequentially(cornerAnimation, colorChangeAnimator,cardElevationAnimator )
animationSet.duration = ANIMATION_INTERVAL_MS;
animationSet.start();
animationSet.addListener(object :AnimatorUpdateListener, Animator.AnimatorListener {
override fun onAnimationEnd(animation: Animator?) {
currentColor = toColor
}
override fun onAnimationUpdate(animation: ValueAnimator?) {}
override fun onAnimationRepeat(animation: Animator?) {}
override fun onAnimationCancel(animation: Animator?) {}
override fun onAnimationStart(animation: Animator?) {}
})
Upvotes: 0
Reputation: 5131
When you use the Builder, all returning dependencies refer to the first Animator, so you had 3 bounces happening simultaneously after the first movement. Unfortunately it seems AnimatorSet is broken on some aspects, one of them being repeats : https://code.google.com/p/android/issues/detail?id=17662
Upvotes: 3
Reputation: 5269
OK so I eventually found a fairly neat way to achieve sequential animation by ignoring the fluent builder, and just using the playSequentially()
method such that:
AnimatorSet as = new AnimatorSet();
as.playSequentially(ObjectAnimator.ofFloat(...), // anim 1
ObjectAnimator.ofFloat(...), // anim 2
ObjectAnimator.ofFloat(...), // anim 3
ObjectAnimator.ofFloat(...)); // anim 4
as.setDuration(600);
as.start();
Still haven't worked out repeating though, other than a dirty hack involving the callback onAnimationEnd in a listener. Must be a simpler way, so perhaps someone can edit this when they know of one.
Anyway, hope the above helps someone.
Upvotes: 29