I have read about Property Animation and Hardware Acceleration but I am still uncertain what is the most efficient way to use the animator classes. (For the sake of this question I don't need to support devices before Honeycomb. So I want to use the animator classes.)
For example, say I have a View. In this view I have a BitmapDrawable that I want to fade in. There are also many other elements within the view that won't change.
What property or object would be best to use with the animator? The drawable? A paint that I am drawing the bitmap with in onDraw? Something else?
How can this be done to be most efficient with hardware acceleration? Will this require calling invalidate for each step of the animation or is there a way to animate just the drawable and not cause the rest of the view to be redrawn completely for each step of the animation?
I guess I imagine an optimal case would be the rest of the view not having to be completely redrawn in software, but rather hardware acceleration efficiently fading the drawable.
Any suggestions or pointers to recommended approaches?
Thanks!
One way to animate Drawables is to load a series of Drawable resources one after another to create an animation. This is a traditional animation in the sense that it is created with a sequence of different images, played in order, like a roll of film. The AnimationDrawable class is the basis for Drawable animations.
Create ImageView in the activity_main. xml along with buttons that will add animation to the view. Navigate to the app > res > layout > activity_main. xml.
With the use of the Object Property Animators, basically they're just math functions that repeatedly call a "setN()" method every X miliseconds where "N" is the property you want to change.
In the example provided in the case of alpha, both would require a call to invalidate()
to redraw the View that you are animating. The difference being when you call setAlpha()
on the View
object, it calls invalidate()
for you. If you were to set the target Object to the Paint
object that is used to draw the drawable, you would still need to call invalidate()
on the View
so it will redraw with the new Paint
parameters.
Ideally you want to set the target to the highest level child you can so the redrawing only happens on the views you want to animate. If you set the target to the root View, for example, it will call invalidate()
on every child in the entire ViewGroup which will in turn call draw()
on every child in the ViewGroup. If you set it to a top level ImageView
, then only ImageView
will be redrawn.
To best utilize the Hardware, you need to use the Layer properties. First, you need to decide what the top-most parent View you want to animate will be. If you want to only fade the Drawable
, then it will be the Drawable
or containing View
. If you want to fade everything, then it will be the root view. Whatever you decide to animate will be applied to the View
as a whole at once.
Use setLayerType()
on the parent view just before you start the Animator. Set it to View#LAYER_TYPE_HARDWARE
. Then set an AnimationListener
and reset the LayerType to View#LAYER_TYPE_SOFTWARE
or View#LAYER_TYPE_NONE
upon completion of the animator.
myParentView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
myObjectAnimator.addListener(new ViewAnimator.AnimatorListener() {
public void onAnimationEnd(Animator animation) {
myParentView.setLayerType(View.LAYER_TYPE_NONE);
}
public void onAnimationRepeat(Animator animation) {
}
public void onAnimationStart(Animator animation) {
}
public void onAnimationCancel(Animator animation) {
myParentView.setLayerType(View.LAYER_TYPE_NONE, null);
}
}
myObjectAnimator.start();
In this case, if you were to translate myParentView
by using the translateX
property, then it will put layer myParentView
and all it's children into one plane. Put it in to hardware memory. Translate the entire view all at once. Then, upon completion, remove myParentView
from memory.
EDIT:
One final note, Alpha wreaks havoc on the CPU. If you have something on half-alpha and translate it across the View, it will be harder to render than if you simply translate the View. Use it sparingly.
Perhaps, you can overlay a new view(which contains the animator only) on your original one. the new view set to Transparent.
the reset you should do is invalid the new view without your original view.
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