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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With