Asd
Asd

Reputation: 313

Any tips for reducing lag when running multiple animations at the same time?

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.

Upvotes: 7

Views: 4460

Answers (2)

user2548538
user2548538

Reputation: 919

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.

Upvotes: 1

Kevin Coppock
Kevin Coppock

Reputation: 134664

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.

Upvotes: 6

Related Questions