美文网首页
Android Canvas 小案例组合动画

Android Canvas 小案例组合动画

作者: 刘小厨 | 来源:发表于2020-04-01 19:01 被阅读0次

    概述

    本文承接Android Canvas总结
    下述小案例仅为Canvas的api的使用总结,非项目使用demo!!!
    先看下效果~

    组合动画

    贴下代码,有问题可见:Android Canvas总结

    public class SplashView extends View {
    
        //旋转圆的画笔
        private Paint mPaint;
        //扩散圆的画笔
        private Paint mHolePaint;
        //属性动画
        private ValueAnimator mValueAnimator;
    
        //背景色
        private int mBackgroundColor = Color.WHITE;
        private int[] mCircleColors;
    
        //表示旋转圆的中心坐标
        private float mCenterX;
        private float mCenterY;
        //表示斜对角线长度的一半,扩散圆最大半径
        private float mDistance;
    
        //6个小球的半径
        private float mCircleRadius = 18;
        //旋转大圆的半径
        private float mRotateRadius = 90;
    
        //当前大圆的旋转角度
        private float mCurrentRotateAngle = 0F;
        //当前大圆的半径
        private float mCurrentRotateRadius = mRotateRadius;
        //扩散圆的半径
        private float mCurrentHoleRadius = 0F;
        //表示旋转动画的时长
        private int mRotateDuration = 1200;
    
        public SplashView(Context context) {
            this(context, null);
        }
    
        public SplashView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
        private void init(Context context) {
    
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    
            mHolePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mHolePaint.setStyle(Paint.Style.STROKE);
            mHolePaint.setColor(mBackgroundColor);
    
            mCircleColors = context.getResources().getIntArray(R.array.splash_circle_colors);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mCenterX = w * 1f / 2;
            mCenterY = h * 1f / 2;
            mDistance = (float) (Math.hypot(w, h) / 2);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (mState == null){
                mState = new RotateState();
            }
            mState.drawState(canvas);
        }
    
        private SplashState mState;
    
        private abstract class SplashState{
            abstract void drawState(Canvas canvas);
        }
    
        //1.旋转
        private class RotateState extends SplashState{
    
            private RotateState(){
                mValueAnimator = ValueAnimator.ofFloat(0, (float) (Math.PI *2));
                mValueAnimator.setRepeatCount(2);
                mValueAnimator.setDuration(mRotateDuration);
                mValueAnimator.setInterpolator(new LinearInterpolator());
                mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        mCurrentRotateAngle = (float) animation.getAnimatedValue();
                        invalidate();
                    }
                });
                mValueAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        mState = new MerginState();
                    }
                });
                mValueAnimator.start();
            }
    
            @Override
            void drawState(Canvas canvas) {
                //绘制背景
                drawBackground(canvas);
                //绘制6个小球
                drawCircles(canvas);
            }
        }
    
        private void drawCircles(Canvas canvas) {
            float rotateAngle = (float) (Math.PI *2 / mCircleColors.length);
            for (int i = 0; i < mCircleColors.length; i++) {
                // x = r * cos(a) + centX;
                // y = r * sin(a) + centY;
                float angle = i * rotateAngle + mCurrentRotateAngle;
                float cx = (float) (Math.cos(angle) * mCurrentRotateRadius + mCenterX);
                float cy = (float) (Math.sin(angle) * mCurrentRotateRadius + mCenterY);
                mPaint.setColor(mCircleColors[i]);
                canvas.drawCircle(cx, cy, mCircleRadius, mPaint);
             }
        }
    
        private void drawBackground(Canvas canvas){
            if (mCurrentHoleRadius > 0){
                //绘制空心圆
                float strokeWidth = mDistance - mCurrentHoleRadius;
                float radius = strokeWidth / 2 + mCurrentHoleRadius;
                mHolePaint.setStrokeWidth(strokeWidth);
                canvas.drawCircle(mCenterX,mCenterY, radius, mHolePaint);
            }else{
                canvas.drawColor(mBackgroundColor);
            }
        }
    
        //2.扩散聚合
        private class MerginState extends SplashState{
    
            private MerginState(){
                mValueAnimator = ValueAnimator.ofFloat(mCircleRadius, mRotateRadius);
    //            mValueAnimator.setRepeatCount(2);
                mValueAnimator.setDuration(mRotateDuration);
                mValueAnimator.setInterpolator(new OvershootInterpolator(10f));
                mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        mCurrentRotateRadius = (float) animation.getAnimatedValue();
                        invalidate();
                    }
                });
                mValueAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        mState = new ExpandState();
                    }
                });
                mValueAnimator.reverse();
            }
    
            @Override
            void drawState(Canvas canvas) {
                drawBackground(canvas);
                drawCircles(canvas);
            }
        }
    
        //3.水波纹
        private class ExpandState extends SplashState{
    
            public ExpandState() {
                mValueAnimator = ValueAnimator.ofFloat(mCircleRadius, mDistance);
    //            mValueAnimator.setRepeatCount(2);
                mValueAnimator.setDuration(mRotateDuration);
                mValueAnimator.setInterpolator(new LinearInterpolator());
                mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        mCurrentHoleRadius = (float) animation.getAnimatedValue();
                        invalidate();
                    }
                });
    
                mValueAnimator.start();
            }
    
            @Override
            void drawState(Canvas canvas) {
                drawBackground(canvas);
            }
        }
    
    }
    

    颜色值

    
        <color name="splash_bg">#F8F6EC</color>
        <color name="orange">#FF9600</color>
        <color name="aqua">#02D1AC</color>
        <color name="yellow">#FFD200</color>
        <color name="blue">#00C6FF</color>
        <color name="green">#00E099</color>
        <color name="pink">#FF3892</color>
    
        <array name="splash_circle_colors">
            <item>@color/blue</item>
            <item>@color/green</item>
            <item>@color/pink</item>
            <item>@color/orange</item>
            <item>@color/aqua</item>
            <item>@color/yellow</item>
        </array>
    

    相关文章

      网友评论

          本文标题:Android Canvas 小案例组合动画

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