美文网首页Android博文自定义Android控件
Android带过渡动画的折叠收缩View

Android带过渡动画的折叠收缩View

作者: William_L | 来源:发表于2017-09-15 10:27 被阅读84次

很多需要实现点击显示和隐藏指定布局的功能,但不带过渡动画的显示和隐藏会显得比较生硬,因此需要自定义一个带过渡动画的控件,代码如下:

public class UMExpandLayout extends RelativeLayout {

    public UMExpandLayout(Context context) {
        this(context, null);
    }

    public UMExpandLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public UMExpandLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initView();
    }

    private View layoutView;
    private int viewHeight;
    private boolean isExpand;
    private long animationDuration;

    private void initView() {
        layoutView = this;
        isExpand = true;
        animationDuration = 300;
        setViewDimensions();
    }

    /**
     * @param isExpand 初始状态是否折叠
     */
    public void initExpand(boolean isExpand) {
        this.isExpand = isExpand;
        if (!isExpand) {
            animateToggle(10);
        }
    }

    /**
     * 设置动画时间
     *
     * @param animationDuration 动画时间
     */
    public void setAnimationDuration(long animationDuration) {
        this.animationDuration = animationDuration;
    }

    /**
     * 获取 subView 的总高度
     * View.post() 的 runnable 对象中的方法会在 View 的 measure、layout 等事件后触发
     */
    private void setViewDimensions() {
        layoutView.post(new Runnable() {
            @Override
            public void run() {
                if (viewHeight <= 0) {
                    viewHeight = layoutView.getMeasuredHeight();
                }
            }
        });
    }

    public static void setViewHeight(View view, int height) {
        final ViewGroup.LayoutParams params = view.getLayoutParams();
        params.height = height;
        view.requestLayout();
    }

    /**
     * 切换动画实现
     */
    private void animateToggle(long animationDuration) {
        ValueAnimator heightAnimation = isExpand ?
                ValueAnimator.ofFloat(0f, viewHeight) : ValueAnimator.ofFloat(viewHeight, 0f);
        heightAnimation.setDuration(animationDuration / 2);
        heightAnimation.setStartDelay(animationDuration / 2);

        heightAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float val = (float) animation.getAnimatedValue();
                setViewHeight(layoutView, (int) val);
            }
        });

        heightAnimation.start();
    }

    public boolean isExpand() {
        return isExpand;
    }

    /**
     * 折叠view
     */
    public void collapse() {
        isExpand = false;
        animateToggle(animationDuration);
    }

    /**
     * 展开view
     */
    public void expand() {
        isExpand = true;
        animateToggle(animationDuration);
    }

    public void toggleExpand() {
        if (isExpand) {
            collapse();
        } else {
            expand();
        }
    }

}

然后就可以在 layout 中使用了:

 <com.eyefate.view.ExpandLayout
                android:id="@+id/setting_about_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/margin_negative_6dp"
                android:background="@android:color/white"
                android:clickable="true">

      <!--您要显示和隐藏的内容-->
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <View
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/height_0.5dp"
                        android:layout_marginLeft="@dimen/margin_8dp"
                        android:layout_marginRight="@dimen/margin_8dp"
                        android:background="@color/color_divide_line" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginBottom="@dimen/margin_12dp"
                        android:layout_marginLeft="@dimen/margin_20dp"
                        android:layout_marginRight="@dimen/margin_20dp"
                        android:layout_marginTop="@dimen/margin_12dp"
                        android:lineSpacingExtra="@dimen/line_space_4dp"
                        android:text="@string/app_description"
                        android:textSize="@dimen/font_text_size_14sp" />
                </LinearLayout>
            </com.eyefate.view.ExpandLayout>

ExpandLayout 的子控件有且只能拥有一个布局,具体效果如下:

f5d9f7aa9a14b3c2c523338e39f58bee.gif

相关文章

网友评论

  • 费麭:动画再加个overshot是不是会更棒?
    William_L:可以尝试下

本文标题:Android带过渡动画的折叠收缩View

本文链接:https://www.haomeiwen.com/subject/xicssxtx.html