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

2

7

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.

Lanugo answered 7/7, 2015 at 1:32 Comment(3)
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?Pentimento
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.Lanugo
Did you get over it successfully?Chongchoo
P
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 https://mcmap.net/q/721112/-android-crash-system-lib-libhwui-so
        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.

Pentimento answered 7/7, 2015 at 2:7 Comment(0)
M
1

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.

Manouch answered 6/10, 2016 at 21:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.