materialDesign过度动画

怎么样,很炫吧

github地址

定义个接口

public interface LoadState {
    void drawState(Canvas canvas);
}

自定义view实现加载动画

/**
 * Created by marc on 2017/6/28.
 */

public class LoadView extends View {
    /**
     * 大圆的半径(里面含有好多小圆)
     */
    private float mRotationRadius = 90;
    /**
     * 小圆的半径
     */
    private float mCircleRadius = 18;
    /**
     * 小圆的颜色列表
     */
    private int[] mCircleColors;

    /**
     * 小圆旋转一周需要的时间
     */
    private long mRotationDuration = 1200;
    /**
     * 其他动画执行的时间(除了旋转的动画)
     */
    private long mSplashDuration = 500;
    /**
     * view的背景颜色
     */
    private int mBgColor = Color.WHITE;
    /**
     * 当前大圆的半径(动态变化)
     */
    private float mCurrentRatationRadios;
    /**
     * 当前大圆旋转的角度(弧度)
     */
    private float mCurrentRotationAngle = 0f;
    /**
     * 空心圆半径
     */
    private float mHoleRadius = 0f;
    /**
     * 绘制圆的画笔
     */
    private Paint mPaint = new Paint();
    /**
     * 绘制背景的画笔
     */
    private Paint mBgPaint = new Paint();

    /**
     * view中心的坐标
     */
    private float mCenterX;
    private float mCenterY;

    /**
     * view对角线的一半
     */
    private float mDiagonalDist;
    /**
     * 保存当前动画状态-->当前在执行那种动画
     */
    private LoadState mState = null;

    /**
     * 小圆之间的间隔角度
     */
    private float mRotationAngle = 0f;
    /**
     * 聚合后缩放圆的半径
     */
    private float mScaleCircle;

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

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

    public LoadView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    /**
     * 初始化
     */
    private void init(Context context) {
        //抗锯齿
        mPaint.setAntiAlias(true);
        mBgPaint.setAntiAlias(true);
        //设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
        mPaint.setDither(true);
        mBgPaint.setDither(true);
        //设置画笔的样式:空心
        mBgPaint.setStyle(Paint.Style.STROKE);
        //设置画笔颜色
        mBgPaint.setColor(mBgColor);
        //旋转的时候大圆的半径不变,为初始化值
        mCurrentRatationRadios = mRotationRadius;
        //聚合后放大圆的初始半径为小圆半径
        mScaleCircle = mCircleRadius;
        //获取颜色数组,小圆的个数和定义颜色的个数相等
        mCircleColors = context.getResources().getIntArray(R.array.circleColor);
        if (mCircleColors.length > 0) {
            //每个小圆之间的间隔角度(弧度)
            mRotationAngle = (float) (2 * Math.PI / mCircleColors.length);
        }
    }

    /**
     * 获取view的中点坐标,view对角线长度的一半
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mCenterX = w / 2f;
        mCenterY = h / 2f;
        mDiagonalDist = (float) (Math.sqrt(w * w + h * h) / 2f);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //如果开始为空,则执行旋转动画
        if (mState == null) {
            mState = new RotationState();
        }
        //这边采用多态的方式,不断改变mState对象类型,执行不同的绘图动作
        mState.drawState(canvas);
        super.onDraw(canvas);
    }

    /**
     * 数据加载完毕,关闭第一个动画,执行后面三个动画
     */
    public void splashAndDisappear() {
        //取消第一个动画
        if (mState != null && mState instanceof RotationState) {
            ((RotationState) mState).cancel();
            post(new Runnable() {
                @Override
                public void run() {
                    mState = new MergingState();
                }
            });
        }
    }

    /**
     * 旋转动画
     */
    private class RotationState implements LoadState {
        private ValueAnimator animator;

        public RotationState() {
            animator = ValueAnimator.ofFloat(0f, (float) (2 * Math.PI));
            animator.setDuration(mRotationDuration);
            //设置无限循环
            animator.setRepeatCount(ValueAnimator.INFINITE);
            //匀速旋转
            animator.setInterpolator(new LinearInterpolator());
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    //获取大圆旋转的当前角度
                    mCurrentRotationAngle = (float) animation.getAnimatedValue();
                    //重绘图像
                    invalidate();
                }
            });
            animator.start();
        }

        @Override
        public void drawState(Canvas canvas) {
            clearCanvas(canvas);
            darwCircle(canvas);
        }

        /**
         * 取消旋转动画
         */
        public void cancel() {
            animator.cancel();
        }
    }

    /**
     * 绘制小圆
     *
     * @param canvas
     */
    private void darwCircle(Canvas canvas) {
        for (int i = 0; i < mCircleColors.length; i++) {
            //设置画笔颜色
            mPaint.setColor(mCircleColors[i]);
            //小圆的x坐标
            float cx = (float) (mCurrentRatationRadios * Math.cos(mCurrentRotationAngle + mRotationAngle * i) + mCenterX);
            float cy = (float) (mCurrentRatationRadios * Math.sin(mCurrentRotationAngle + mRotationAngle * i) + mCenterY);
            canvas.drawCircle(cx, cy, mCircleRadius, mPaint);
        }
    }

    /**
     * 清空画布
     *
     * @param canvas
     */
    private void clearCanvas(Canvas canvas) {
        //如果空心圆的半径为0,则清空画布,如果mHoleRadius不为零,说明正在执行扩散动画
        if (mHoleRadius > 0f) {
            //画笔的宽度
            mBgPaint.setStrokeWidth(mDiagonalDist - mHoleRadius);
            //空心圆的半径
            float radius = mDiagonalDist / 2 + mHoleRadius / 2;
            canvas.drawCircle(mCenterX, mCenterY, radius, mBgPaint);
        } else {
            canvas.drawColor(mBgColor);
        }
    }


    /**
     * 聚合动画
     */
    private class MergingState implements LoadState {
        private ValueAnimator animator;

        public MergingState() {
            animator = ValueAnimator.ofFloat(0f, mRotationRadius);
            //开始有个弹射效果,输入的参数越大,弹射效果越明显
            animator.setInterpolator(new OvershootInterpolator(6f));
            animator.setDuration(mSplashDuration);
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mCurrentRatationRadios = (float) animation.getAnimatedValue();
                    invalidate();
                }
            });
            //反向计算
            animator.reverse();
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    post(new Runnable() {
                        @Override
                        public void run() {
                            mState = new CircleStae();
                        }
                    });
                }
            });
        }

        @Override
        public void drawState(Canvas canvas) {
            clearCanvas(canvas);
            darwCircle(canvas);
        }
    }

    /**
     * 圆缩放动画
     */
    private class CircleStae implements LoadState {
        private ValueAnimator animator;

        public CircleStae() {
            animator = ValueAnimator.ofFloat(mCircleRadius, 2.5f * mCircleRadius, mCircleRadius);
            animator.setDuration(mSplashDuration);
            animator.setInterpolator(new LinearInterpolator());
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    //当前圆的圆心
                    mScaleCircle = (float) animation.getAnimatedValue();
                    //重绘图像
                    invalidate();
                }
            });
            animator.start();
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    post(new Runnable() {
                        @Override
                        public void run() {
                            mState = new ExpandingStae();
                        }
                    });
                }
            });
        }

        @Override
        public void drawState(Canvas canvas) {
            clearCanvas(canvas);
            canvas.drawCircle(mCenterX, mCenterY, mScaleCircle, mPaint);
        }
    }


    /**
     * 扩散动画
     */
    private class ExpandingStae implements LoadState {
        private ValueAnimator animator;

        public ExpandingStae() {
            animator = ValueAnimator.ofFloat(0, mDiagonalDist);
            animator.setDuration(mSplashDuration);
            //扩散我这边使用的是匀速,可以换成加速:AccelerateInterpolator
            animator.setInterpolator(new LinearInterpolator());
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    //获取空心圆的半径
                    mHoleRadius = (float) animation.getAnimatedValue();
                    //重绘图像
                    invalidate();
                }
            });
            animator.start();
        }

        @Override
        public void drawState(Canvas canvas) {
            clearCanvas(canvas);
        }
    }
}

activity中执行

public class MdLoadActivity extends AppCompatActivity {
    private LoadView loadView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SplashView splashView = new SplashView(MdLoadActivity.this);
        ContentView contentView = new ContentView(MdLoadActivity.this);
        loadView = new LoadView(this);
        FrameLayout fl = new FrameLayout(this);
//        fl.addView(splashView);
        fl.addView(contentView);
        fl.addView(loadView);
        setContentView(fl);
        handler.postDelayed(() -> loadView.splashAndDisappear(), 2000);
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值