Android自动伸展动画

一、前言:

5111a36f9d031610259729ee2cf928ea.gif

1、java工具类:

package com.weifeng.hobby.commonui.tools;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;

public class HiddenAnimUtils5 {

    private int mHeight;//伸展高度

    private View hideView,down;//需要展开隐藏的布局,开关控件

    private RotateAnimation animation;//旋转动画

    /**

     * 构造器(可根据自己需要修改传参)

     * @param context 上下文

     * @param hideView 需要隐藏或显示的布局view

     * @param down 按钮开关的view

     * @param height 布局展开的高度(根据实际需要传)

     */

    public static HiddenAnimUtils5 newInstance(Context context, View hideView, View down, int height){

        return new HiddenAnimUtils5(context,hideView,down,height);

    }

    private HiddenAnimUtils5(Context context, View hideView, View down, int height){

        this.hideView = hideView;

        this.down = down;

        float mDensity = context.getResources().getDisplayMetrics().density;

        mHeight = (int) (mDensity * height + 0.5);//伸展高度

    }

    /**

     * 开关

     */

    public void toggle(){

        startAnimation();

        if (View.VISIBLE == hideView.getVisibility()) {

            closeAnimate(hideView);//布局隐藏

        } else {

            openAnim(hideView);//布局铺开

        }

    }

    /**

     * 开关旋转动画

     */

    private void startAnimation() {

        if (View.VISIBLE == hideView.getVisibility()) {

            animation = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

        } else {

            animation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

        }

        animation.setDuration(30);//设置动画持续时间

        animation.setInterpolator(new LinearInterpolator());

        animation.setRepeatMode(Animation.REVERSE);//设置反方向执行

        animation.setFillAfter(true);//动画执行完后是否停留在执行完的状态

        down.startAnimation(animation);

    }

    private void openAnim(View v) {

        v.setVisibility(View.VISIBLE);

        ValueAnimator animator = createDropAnimator(v, 0, mHeight);

        animator.start();

    }

    private void closeAnimate(final View view) {

        int origHeight = view.getHeight();

        ValueAnimator animator = createDropAnimator(view, origHeight, 0);

        animator.addListener(new AnimatorListenerAdapter() {

            @Override

            public void onAnimationEnd(Animator animation) {

                view.setVisibility(View.GONE);

            }

        });

        animator.start();

    }

    private ValueAnimator createDropAnimator(final View v, int start, int end) {

        ValueAnimator animator = ValueAnimator.ofInt(start, end);

        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override

            public void onAnimationUpdate(ValueAnimator arg0) {

                int value = (int) arg0.getAnimatedValue();

                ViewGroup.LayoutParams layoutParams = v.getLayoutParams();

                layoutParams.height = value;

                v.setLayoutParams(layoutParams);

            }

        });

        return animator;

    }


}

kotlin写法

package com.weifeng.hobby.commonui.tools

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.view.View
import android.view.animation.Animation
import android.view.animation.LinearInterpolator
import android.view.animation.RotateAnimation

class HiddenAnimUtils private constructor(
        context: Context, private val hideView: View, //需要展开隐藏的布局,开关控件
        private val down: View, height: Int,
) {
    private val mHeight //伸展高度
            : Int
    private var animation //旋转动画
            : RotateAnimation? = null

    /**
     *
     * 开关
     *
     */
    fun toggle() {
        startAnimation()
        if (View.VISIBLE == hideView.visibility) {
            closeAnimate(hideView) //布局隐藏
        } else {
            openAnim(hideView) //布局铺开
        }
    }

    /**
     *
     * 开关旋转动画
     *
     */
    private fun startAnimation() {
        animation = if (View.VISIBLE == hideView.visibility) {
            RotateAnimation(0f, 180f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f)
        } else {
            RotateAnimation(180f, 0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f)
        }
        animation!!.duration = 40 //设置动画持续时间
        animation!!.interpolator = LinearInterpolator()
        animation!!.repeatMode = Animation.REVERSE //设置反方向执行
        //  animation!!.repeatMode = Animation.RESTART //设置反方向执行
        animation!!.fillAfter = true //动画执行完后是否停留在执行完的状态
        down.startAnimation(animation)
    }

    private fun openAnim(v: View) {
        v.visibility = View.VISIBLE
        val animator = createDropAnimator(v, 0, mHeight)
        animator.start()
    }

    private fun closeAnimate(view: View) {
        val origHeight = view.height
        val animator = createDropAnimator(view, origHeight, 0)
        animator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                view.visibility = View.GONE
            }
        })
        animator.start()
    }

    private fun createDropAnimator(v: View, start: Int, end: Int): ValueAnimator {
        val animator = ValueAnimator.ofInt(start, end)
        animator.addUpdateListener { arg0 ->
            val value = arg0.animatedValue as Int
            val layoutParams = v.layoutParams
            layoutParams.height = value
            v.layoutParams = layoutParams
        }
        return animator
    }

    companion object {
        /**
         *
         * 构造器(可根据自己需要修改传参)
         *
         * @param context 上下文
         *
         * @param hideView 需要隐藏或显示的布局view
         *
         * @param down 按钮开关的view
         *
         * @param height 布局展开的高度(根据实际需要传)
         */
        fun newInstance(context: Context, hideView: View, down: View, height: Int): HiddenAnimUtils {
            return HiddenAnimUtils(context, hideView, down, height)
        }
    }

    init {
        //dp转化为px
        val mDensity = context.resources.displayMetrics.density
        mHeight = (mDensity * height + 0.5).toInt() //伸展高度
    }
}

2、调用:

/**
* hidddle:隐藏或者显示的布局
* ivUp: 上下箭头
* height:布局的高度,单位是dp
*/
HiddenAnimUtils.newInstance(context, hidddle,ivUp, height).toggle()
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容