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!
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.
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.
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); } }); }
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