6

Once my app reaches ~4+ animations running concurrently, the animations start to lag a little. Are there any ways I could fix/optimize that? I am using ObjectAnimator and ValueAnimator.

Asd
  • 303
  • 2
  • 7
  • Can you give more information? What are you animating? How complex are the animations? Are the animations all on different views? Are the views redrawing during the animations? – Kevin Coppock Jul 07 '15 at 01:45
  • Mostly translations, scaling, and animated colour transitions. The animations happen on different views. I am not sure if views redraw during the animations, but I am not calling invalidate() manually. – Asd Jul 07 '15 at 01:59
  • Did you get over it successfully? – eC Droid Nov 23 '17 at 13:59

2 Answers2

6

So, if the views are not having to redraw themselves during the animations, you can enable hardware layers during the duration of the animations. For instance:

final View myView = // your view
Animator animator = ObjectAnimator.ofFloat(myView, View.ALPHA, 0f, 1f);
animator.setDuration(1000);
animator.addAnimatorListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animator) {
        myView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
    }

    @Override
    public void onAnimationCancel(Animator animator) {
        myView.setLayerType(View.LAYER_TYPE_NONE, null);
    }

    @Override
    public void onAnimationEnd(Animator animator) {
        // See http://stackoverflow.com/a/19615205/321697
        myView.post(new Runnable() {
            @Override
            public void run() {
                myView.setLayerType(View.LAYER_TYPE_NONE, null);
            }
        }
    }
}
animator.start();

I'd suggest breaking that listener implementation out into a separate class, but the general idea is that you want to put the view into a hardware backed layer as soon as the animation starts (animation properties such as translation, rotation, scale, and alpha are incredibly cheap when backed by a hardware layer) and then clear the layer once the animation is complete.

In the onAnimationEnd callback, you'll notice a link to another answer where there's a bug with 4.0.x if you set the layer type to none in the onAnimationEnd callback. If you're only supporting 4.1 and above, the runnable indirection shouldn't be necessary.

EDIT: If you're animating a color transition, you probably don't want to do the above, as changing the color of the view will require it to be redrawn, causing it to rebuild the hardware layer on each frame.

Kevin Coppock
  • 133,643
  • 45
  • 263
  • 274
0

If you have not used ViewPropertyAnimator, you better do. I moved and flipped(changed picture) 52 imageViews (one deck of playing cards) smoothly. Here's an example on how to use ViewPropertyAnimator.

Community
  • 1
  • 1
user2548538
  • 869
  • 1
  • 8
  • 14