如何使用动画扩展布局的高度?

51

我找不到一个好的示例来说明如何做到这一点。

我有一个设置了高度为x的RelativeLayout。

我想添加一个按钮,将高度扩展到x+y的高度。

请问有没有人能够给我推荐一个好的关于如何以编程方式实现它的示例?


1
请点击以下链接查看我提供的展开和折叠解决方案:https://dev59.com/omEi5IYBdhLWcg3wwemq - Ferran Maylinch
最佳解决方案:https://dev59.com/K2sz5IYBdhLWcg3wDjto#8162779 - karanatwal.github.io
5个回答

74

您标记了最接近的解决方案,但这才是确切的解决方案。我也曾遇到过同样的问题。希望这个答案能帮助其他人。

实例化ResizeAnimation

ResizeAnimation resizeAnimation = new ResizeAnimation(
     view, 
     targetHeight, 
     startHeight
); 
resizeAnimation.setDuration(duration); 
view.startAnimation(resizeAnimation);

ResizeAnimation 类应该像这样:

public class ResizeAnimation extends Animation {
    final int targetHeight;
    View view;
    int startHeight;

    public ResizeAnimation(View view, int targetHeight, int startHeight) {
        this.view = view;
        this.targetHeight = targetHeight;
        this.startHeight = startHeight;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        int newHeight = (int) (startHeight + targetHeight * interpolatedTime);
        //to support decent animation, change new heigt as Nico S. recommended in comments
        //int newHeight = (int) (startHeight+(targetHeight - startHeight) * interpolatedTime);
        view.getLayoutParams().height = newHeight;
        view.requestLayout();
    }

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

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

24
谢谢!我刚刚修改了newHeight的计算方式,以支持下降高度动画。 新的计算公式为:int newHeight = (int) (startHeight+(targetHeight - startHeight) * interpolatedTime); - Nico.S
1
奇怪的是这根本不起作用,什么都没有发生。 - Lampione
1
它的反义词是什么? - Cyph3rCod3r
它的反向是什么? - suulisin
1
谢谢分享。但我认为动画中的newHeight应该是startHeight + DeltaHeight * interpolatedTime,其中DeltaHeight是(目标高度 - 起始高度)。 - Chauyan
显示剩余6条评论

17

你需要一个比例动画,这里是官方文档。

这是代码中的内容。

private void animate() {
    ImageView imageView = (ImageView) findViewById(R.id.ImageView01);
    ScaleAnimation scale = new ScaleAnimation((float)1.0, (float)1.5, (float)1.0, (float)1.5);
    scale.setFillAfter(true);
    scale.setDuration(500);
    imageView.startAnimation(scale); 
}

缩放?我以为我需要翻译。我正在调整LayoutParams,你确定我需要缩放吗? - piojo
3
如果你想增加尺寸,就需要进行缩放。如果只是想移动物体,就需要进行平移。 - Janusz
好的,但我需要一个比例动画,它可以得到起始高度和结束高度,而不是缩放多少。 - piojo
2
如果你有100dip或者100px,并且设置了缩放因子为1,那么视图的大小将会是100dip / 100px。 - Lukap

16

请查看以下已编辑的新答案。但在这里,您需要知道确切的新高度。

public class LayoutAnimationActivity extends Activity {
    RelativeLayout ril1;
    Button btn;
    int initialHeight;
    int actualHeight;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main2);
        ril1 = (RelativeLayout) findViewById(R.id.relativeLayout1);
        btn = new Button(this);
        btn.setWidth(100);
        btn.setHeight(200);
        btn.setText("Button");
        actualHeight = 210;
        Ani a = new Ani();
        a.setDuration(2000);
        ril1.startAnimation(a);
    }

    class Ani extends Animation {
        public Ani() {}

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            int newHeight;

            newHeight = (int) (initialHeight * interpolatedTime);

            ril1.removeAllViews();
            btn.setWidth(100);
            btn.setHeight(300);
            btn.setText("as");
            ril1.addView(btn);             
            ril1.getLayoutParams().height = newHeight;
            ril1.requestLayout();
        }

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

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

好的,它扩展了布局(我做了一些更改),但没有动画。 - piojo
1
我不明白这个按钮与所有这些有什么关系。为什么你要删除所有视图并设置新的宽度、高度和文本到按钮上。这段代码只是扩展了布局,如何折叠它? - piojo
1
你是最接近的。我找到了这个答案,它很有帮助: - piojo
8
公共类layout_animation扩展了Activity。 - 你是代码风格连环杀手。 - Anton Kizema
1
它可以展开,但无法折叠。 - avez raj

6

没有使用Animation类的两种简单方法:

1)在xml布局文件中设置android:animateLayoutChanges="true"

2)使用ViewProperty动画器

layout.setPivot(0);
layout.animate().scaleY(scaleFactor).setDuration(500);

枢轴告诉视图从哪里开始缩放,默认在中间,但根据我的经验,这几乎从来不是你想要的。持续时间是可选的(默认为1000)。


2
final Button button1 = (Button) view.findViewById(R.id.button);
    final CollapseAnimator animator = new CollapseAnimator(topLayout);

    final ViewTreeObserver.OnGlobalLayoutListener listener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int mHeight = button1.getMeasuredHeight();
            KLog.i("onGlobalLayout() mHeight:" + mHeight);
            animator.setValues(mHeight*2, mHeight);

        }
    };
    button1.getViewTreeObserver().addOnGlobalLayoutListener(listener);
    button1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            view.post(new Runnable() {
                @Override
                public void run() {
                    button1.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
                    animator.collapse();

                }
            });

        }
    });

和类

public class CollapseAnimator {
    private View view;
    private boolean collapse=true;
    private int duation=300;
    private int destHeight=300;
    private ValueAnimator animator;
    private int originHeight=0;
    private int from=0;
    private int to=0;


    public CollapseAnimator(View view ) {
        this.view = view;
    }

    public void setValues(int destHeight,int originHeight){
        this.destHeight = destHeight;
        this.originHeight=originHeight;
        from=originHeight;
        to=originHeight;
    }
    public void collapse(){


        from=to;
        if(collapse){

            to=destHeight;
            collapse=false;
        }else{
            to=originHeight;
            collapse=true;
        }
        KLog.i("from:" + from+",to:"+to);
        animator = ValueAnimator.ofInt(from, to);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int val = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
                layoutParams.height = val;
                view.setLayoutParams(layoutParams);
            }
        });
        animator.setDuration(duation);
        animator.start();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接