Android: Expand/collapse animation

后端 未结 30 2458
说谎
说谎 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:28

    @Tom Esterez's answer, but updated to use view.measure() properly per Android getMeasuredHeight returns wrong values !

        // http://easings.net/
        Interpolator easeInOutQuart = PathInterpolatorCompat.create(0.77f, 0f, 0.175f, 1f);
    
        public static Animation expand(final View view) {
            int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) view.getParent()).getWidth(), View.MeasureSpec.EXACTLY);
            int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            view.measure(matchParentMeasureSpec, wrapContentMeasureSpec);
            final int targetHeight = view.getMeasuredHeight();
    
            // Older versions of android (pre API 21) cancel animations for views with a height of 0 so use 1 instead.
            view.getLayoutParams().height = 1;
            view.setVisibility(View.VISIBLE);
    
            Animation animation = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
    
                   view.getLayoutParams().height = interpolatedTime == 1
                        ? ViewGroup.LayoutParams.WRAP_CONTENT
                        : (int) (targetHeight * interpolatedTime);
    
                view.requestLayout();
            }
    
                @Override
                public boolean willChangeBounds() {
                    return true;
                }
            };
    
            animation.setInterpolator(easeInOutQuart);
            animation.setDuration(computeDurationFromHeight(view));
            view.startAnimation(animation);
    
            return animation;
        }
    
        public static Animation collapse(final View view) {
            final int initialHeight = view.getMeasuredHeight();
    
            Animation a = new Animation() {
                @Override
                protected void applyTransformation(float interpolatedTime, Transformation t) {
                    if (interpolatedTime == 1) {
                        view.setVisibility(View.GONE);
                    } else {
                        view.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime);
                        view.requestLayout();
                    }
                }
    
                @Override
                public boolean willChangeBounds() {
                    return true;
                }
            };
    
            a.setInterpolator(easeInOutQuart);
    
            int durationMillis = computeDurationFromHeight(view);
            a.setDuration(durationMillis);
    
            view.startAnimation(a);
    
            return a;
        }
    
        private static int computeDurationFromHeight(View view) {
            // 1dp/ms * multiplier
            return (int) (view.getMeasuredHeight() / view.getContext().getResources().getDisplayMetrics().density);
        }
    

提交回复
热议问题