Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the optimal way to animate a drawable within a view using the animator classes?

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!

like image 534
cottonBallPaws Avatar asked Oct 31 '12 04:10

cottonBallPaws


People also ask

How do you animate a drawable in android?

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.

How do you animate a view?

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.


2 Answers

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.

like image 96
DeeV Avatar answered Dec 17 '22 12:12

DeeV


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.

like image 37
landry Avatar answered Dec 17 '22 10:12

landry