Android: Expand/collapse animation

后端 未结 30 2214
说谎
说谎 2020-11-22 05:01

Let\'s say I have a vertical linearLayout with :

[v1]
[v2]

By default v1 has visibily = GONE. I would like to show v1 with an expand animat

30条回答
  •  一生所求
    2020-11-22 05:23

    Adding to Tom Esterez's excellent answer and Erik B's excellent update to it, I thought I'd post my own take, compacting the expand and contract methods into one. This way, you could for example have an action like this...

    button.setOnClickListener(v -> expandCollapse(view));
    

    ... which calls the method below and letting it figure out what to do after each onClick()...

    public static void expandCollapse(View view) {
    
        boolean expand = view.getVisibility() == View.GONE;
        Interpolator easeInOutQuart = PathInterpolatorCompat.create(0.77f, 0f, 0.175f, 1f);
    
        view.measure(
            View.MeasureSpec.makeMeasureSpec(((View) view.getParent()).getWidth(), View.MeasureSpec.EXACTLY),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        );
    
        int height = view.getMeasuredHeight();
        int duration = (int) (height/view.getContext().getResources().getDisplayMetrics().density);
    
        Animation animation = new Animation() {
            @Override protected void applyTransformation(float interpolatedTime, Transformation t) {
                if (expand) {
                    view.getLayoutParams().height = 1;
                    view.setVisibility(View.VISIBLE);
                    if (interpolatedTime == 1) {
                        view.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
                    } else {
                        view.getLayoutParams().height = (int) (height * interpolatedTime);
                    }
                    view.requestLayout();
                } else {
                    if (interpolatedTime == 1) {
                        view.setVisibility(View.GONE);
                    } else {
                        view.getLayoutParams().height = height - (int) (height * interpolatedTime);
                        view.requestLayout();
                    }
                }
            }
            @Override public boolean willChangeBounds() {
                return true;
            }
        };
    
        animation.setInterpolator(easeInOutQuart);
        animation.setDuration(duration);
        view.startAnimation(animation);
    
    }
    

提交回复
热议问题