Android:展开/折叠动画 [英] Android: Expand/collapse animation

查看:125
本文介绍了Android:展开/折叠动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个垂直的 linearLayout :

Let's say I have a vertical linearLayout with :

[v1]
[v2]

默认情况下 v1 具有 visibily = GONE.我想用展开动画显示 v1,同时按下 v2.

By default v1 has visibily = GONE. I would like to show v1 with an expand animation and push down v2 at the same time.

我尝试过这样的事情:

Animation a = new Animation()
{
    int initialHeight;

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final int newHeight = (int)(initialHeight * interpolatedTime);
        v.getLayoutParams().height = newHeight;
        v.requestLayout();
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        initialHeight = height;
    }

    @Override
    public boolean willChangeBounds() {
        return true;
    }
};

但使用此解决方案,动画开始时我会眨眼.我认为这是由于 v1 在应用动画之前显示全尺寸造成的.

But with this solution, I have a blink when the animation starts. I think it's caused by v1 displaying full size before the animation is applied.

使用javascript,这是一行jQuery!有什么简单的方法可以用 android 做到这一点?

With javascript, this is one line of jQuery! Any simple way to do this with android?

推荐答案

我看到这个问题很流行,所以我发布了我的实际解决方案.主要优点是您不必知道应用动画的展开高度,并且一旦视图展开,它会在内容更改时调整高度.它对我很有用.

I see that this question became popular so I post my actual solution. The main advantage is that you don't have to know the expanded height to apply the animation and once the view is expanded, it adapts height if content changes. It works great for me.

public static void expand(final View v) {
    int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) v.getParent()).getWidth(), View.MeasureSpec.EXACTLY);
    int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    v.measure(matchParentMeasureSpec, wrapContentMeasureSpec);
    final int targetHeight = v.getMeasuredHeight();

    // Older versions of android (pre API 21) cancel animations for views with a height of 0.
    v.getLayoutParams().height = 1;
    v.setVisibility(View.VISIBLE);
    Animation a = new Animation()
    {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            v.getLayoutParams().height = interpolatedTime == 1
                    ? LayoutParams.WRAP_CONTENT
                    : (int)(targetHeight * interpolatedTime);
            v.requestLayout();
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };

    // Expansion speed of 1dp/ms
    a.setDuration((int)(targetHeight / v.getContext().getResources().getDisplayMetrics().density));
    v.startAnimation(a);
}

public static void collapse(final View v) {
    final int initialHeight = v.getMeasuredHeight();

    Animation a = new Animation()
    {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            if(interpolatedTime == 1){
                v.setVisibility(View.GONE);
            }else{
                v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
                v.requestLayout();
            }
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };

    // Collapse speed of 1dp/ms
    a.setDuration((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density));
    v.startAnimation(a);
}

正如@Jefferson 在评论中提到的,您可以通过更改动画的持续时间(以及速度)来获得更流畅的动画.目前已设置为1dp/ms的速度

As mentioned by @Jefferson in the comments, you can obtain a smoother animation by changing the duration (and hence the speed) of the animation. Currently, it has been set at a speed of 1dp/ms

这篇关于Android:展开/折叠动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆