Android 带有 ValueAnimator 的 LinearLayout 容器高度动画
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11935216/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Animation of height of LinearLayout container with ValueAnimator
提问by span
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.
我有一个 LinearLayout 用作一些按钮和文本视图的容器,我想为它们的高度设置动画,以在用户按下“显示”按钮时给人一种布局向下滑动的印象。
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.
我在我的 xml 中将 LinearLayout 设置为 layout_height="0dp" 和可见性="gone"。然后我希望将它设置为可见,并且需要任何高度来包装内容。目前,我什至根本无法对其进行动画处理,更不用说包装内容的高度了。
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!
也许问题是我如何设置 LinearLayout 的高度?还是我误解了 ValueAnimator 的功能?我已经环顾了 Chet Haase 的博客文章,但它们不包含任何特定的高度动画示例。我也没有找到关于如何使用 3.0+ 中的 API 处理高度动画的好例子。希望得到一些帮助,谢谢!
回答by span
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()
.
查看这篇博文:http: //tech.chitgoks.com/2011/10/29/android-animation-to-expand-collapse-view-its-children/我发现我不应该使用view.invalidate()
布局重绘。我应该使用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):
我只是想添加一个关于如何获取 LinearLayout 的高度以及使动画动态化的注释。要获得高度,需要先绘制所有视图。因此,我们必须监听一个告诉我们绘图已完成的事件。这可以通过像这样的 onResume() 方法来完成(注意,在我的 xml 中,我已经将容器声明为 wrap_content 的高度,它也是可见的,因为我想从一开始就隐藏它,我在测量它之后这样做):
@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);
}
});
}