Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android ViewPropertyAnimator doesn't scale at the same time

I am trying to use the ViewPropertyAnimator to scale a view (an indeterminate ProgressBar) each time a button is pressed.

loadingCircle.animate().scaleY(1.5f).scaleX(1.5f).setDuration(100f);

I have an animatorListener that scales back to normal onAnimationEnd:

loadingCircle.animate().scaleY(1.0f).scaleX(1.0f).setDuration(100f);

Nothing too complicated. However, it doesn't seem to scale both x and y at the same time always.

Usually it does it right the first time, sometimes the second time. When it doesn't work, it only animates the last operation in the chain. If it's scaleX, it will only scale X. If I swap it around, it will only scale Y.

Documentation for scaleX and scaleY say:

Animations already running on the property will be canceled

However, I thought that ViewPropertyAnimator was able to be chained, and this comment only applies for new animations (on a different line of code). Am I doing something wrong, or have I found a bug?

I'm running Android 4.2.2 on a GalaxyS4. Stock ROM, but rooted. If that makes a difference.

like image 289
Xebozone Avatar asked Sep 24 '14 19:09

Xebozone


2 Answers

I believe this is indeed a bug. I worked around this by using ObjectAnimator instead of ViewPropertyAnimator to get the same result. So, yours would look something like:

ObjectAnimator animX = ObjectAnimator.ofFloat(loadingCircle, "scaleX", 1.0f);
ObjectAnimator animY = ObjectAnimator.ofFloat(loadingCircle, "scaleY", 1.0f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();

Source: http://developer.android.com/guide/topics/graphics/prop-animation.html#view-prop-animator

like image 50
dennisdrew Avatar answered Nov 05 '22 04:11

dennisdrew


Reading through the source code the behavior you describe makes perfect sense and is by design. When you add an animation, it will start on the next runloop/when it can. Sometimes you'll be able to get both animations in there before this happens, sometimes you won't.

If you tell it to not start the animation immediately, then you'll have enough time to add all of your animations. This obviously is a bit of a hack.

You could probably try something like this:

loadingCircle.animate()
    .setStartDelay(1000) //prevent the animation from starting
    .scaleY(1.5f)
    .scaleX(1.5f)
    .setDuration(100f)
    .setStartDelay(0)
    .start();
like image 45
Sam Dozor Avatar answered Nov 05 '22 04:11

Sam Dozor