使用ValueAnimator动画LinearLayout容器的高度

时间:2012-08-13 13:27:49

标签: android animation android-linearlayout

我有一个LinearLayout,我用它作为一些按钮和textview的容器,我想设置高度的动画,以便在用户按下“show”按钮时给出一个向下滑动的印象。

我在我的xml中将LinearLayout设置为layout_height =“0dp”并且visibility =“gone”。然后,我希望将其设置为可见,并且需要包含内容的高度。目前我的问题甚至都是动画片,请不要担心包装内容的高度。

这是我制作动画的方法:

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();
}

也许问题是我如何设置LinearLayout的高度?或者我误解了ValueAnimator的功能?我查看了Chet Haase的博客文章,但它们没有包含任何特定高度的动画示例。我也没有能够找到如何使用3.0+的API来处理高度动画的好例子。希望对此有所帮助,谢谢!

1 个答案:

答案 0 :(得分:58)

查看此博文:http://tech.chitgoks.com/2011/10/29/android-animation-to-expand-collapse-view-its-children/我发现我不应该使用view.invalidate()重新绘制布局。我应该使用view.requestLayout()

因此代码就像这样:

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();
        }
    });

我只是想添加一个关于如何获取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);
            }
        });
    }