Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animation of height of LinearLayout container with ValueAnimator

Tags:

I have a LinearLayout that I use as a container for some buttons and textview's that I would like to animate the height of to give an impression of the layout sliding down when the user presses a "show" button.

I have set the LinearLayout to layout_height="0dp" and visibility="gone" in my xml. I then wish to set it to be visible and whatever height is need to wrap the content. At the moment I'm having issues even animating it at all, nevermind the wrap content height.

Here's my method for animating:

private void toggle(final LinearLayout v) {     v.setVisibility(View.VISIBLE);     ValueAnimator va = ValueAnimator.ofInt(0, 300);     va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {         public void onAnimationUpdate(ValueAnimator animation) {             Integer value = (Integer) animation.getAnimatedValue();             v.getLayoutParams().height = value.intValue();             v.invalidate();          }     });      va.start(); } 

Perhaps the problem is how I am setting the height of the LinearLayout? Or am I misunderstanding the function of the ValueAnimator? I've looked around at the blog post's by Chet Haase but they do not contain any specific height animation examples. Neither have I been able to find and good examples of how to work with animations of height using API's from 3.0+. Would love some help on this, thanks!

like image 701
span Avatar asked Aug 13 '12 13:08

span


People also ask

What is the difference between ValueAnimator and ObjectAnimator?

As shown in code above, ValueAnimator is almost like ObjectAnimator , except it doesn't have a specific view to target. It has to have a listener — i.e. addUpdateListner — to listen to the value change and behave accordingly. This added more code, but better customization for it.

What is property animation?

The property animation system is a robust framework that allows you to animate almost anything. You can define an animation to change any object property over time, regardless of whether it draws to the screen or not.


1 Answers

Looking at this blog post: http://tech.chitgoks.com/2011/10/29/android-animation-to-expand-collapse-view-its-children/ I found that I shouldn't use view.invalidate() to have the layout redrawn. I should use view.requestLayout().

Thus the code becomes something like this:

ValueAnimator va = ValueAnimator.ofInt(0, height);     va.setDuration(700);     va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {         public void onAnimationUpdate(ValueAnimator animation) {             Integer value = (Integer) animation.getAnimatedValue();             v.getLayoutParams().height = value.intValue();             v.requestLayout();         }     }); 

I just wanted to add a note on how to get the height of the LinearLayout as well to make the animation dynamic. To get the height all the views need to be drawn first. Therfor we have to listen for an event that tells us that the drawing is done. This can be done from the onResume() method like this (note that in my xml I have declared the container to wrap_content for height and it is also visible, since I want to hide it from the start I do that efter measuring it):

@Override     public void onResume() {         super.onResume();         final ViewTreeObserver vto = filterContainer.getViewTreeObserver();         vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {             @Override             public void onGlobalLayout() {                 height = filterContainer.getHeight();                 filterContainer.setVisibility(View.GONE);                 filterContainer.getLayoutParams().height = 0;                 filterContainer.requestLayout();                 ViewTreeObserver obs = filterContainer.getViewTreeObserver();                 obs.removeGlobalOnLayoutListener(this);             }         });     } 
like image 174
span Avatar answered Sep 23 '22 17:09

span