美文网首页自定义View篇Android开发学习
Android 属性动画+自定义view实现加载动画

Android 属性动画+自定义view实现加载动画

作者: Levipeng | 来源:发表于2020-01-21 12:02 被阅读0次
    如图 splash.gif

    思路分析

    过程拆分
    1.画6个小圆圈
    2.小圆圈转动起来
    3.小圆圈聚合
    4.开始扩散
    首先确定6个圆的坐标,画出小圆,圆要转动,就是要同步改变每个小圆的坐标,小圆的运动轨迹是个圆。所以使用属性动画,属性动画的变化区别设置为0-2π,然后使用勾股定律求出旋转的圆心坐标,重绘。就能实现旋转效果了。然后只要改变这个大圆的半径就能实现聚合效果。最后扩散效果这个思路就很sao,就是画一个圆,画笔的style设置成STROKE,只要改变Stroke的宽度就行了。是不是很简单。
    思路都有了开始撸码

    public class SplashView extends View {
        //小圆半径
        private int smallCircleRadius = 20;
        //大圆半径
        private int bigCircleRadius = 100;
        //小圆画笔
        private Paint mPaintSmallCircle;
        //小圆颜色
        private int[] colorsCircle;
        //小圆之间的角度
        private float angle;
        //属性动画旋转角度
        private float scaleAngle;
        //属性动画变化半径
        private int scaleRadiu;
        private SlpashState drawState;
        //屏幕对角线的一半
        private float expandRadius;
        //扩散画笔
        private Paint mPaintExpand;
        private float mPaintExpandMove;
    
    
        public SplashView(Context context) {
            this(context, null);
        }
    
        public SplashView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
        private void init(Context context) {
            colorsCircle = context.getResources().getIntArray(R.array.colorCircle);
            mPaintSmallCircle = new Paint();
            mPaintSmallCircle.setAntiAlias(true);
            mPaintSmallCircle.setStyle(Paint.Style.FILL);
            mPaintExpand=new Paint();
            mPaintExpand.setAntiAlias(true);
            mPaintExpand.setStyle(Paint.Style.STROKE);
            mPaintExpand.setColor(Color.WHITE);
            angle = (float) (2 * Math.PI / colorsCircle.length);
    
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            expandRadius= (float) Math.sqrt(w*w+h*h)/2;
        }
    
        public void cancle() {
            if (drawState instanceof RotateState){
                //((RotateState)drawState).cancle();
                drawState=new MergingState();
            }
        }
    
        //使用策略模式
        private abstract class SlpashState {
            public abstract void drawState(Canvas canvas);
        }
    
        //旋转状态
        private class RotateState extends SlpashState {
            private  ValueAnimator valueAnimator;
    
            public RotateState() {
                valueAnimator = ValueAnimator.ofFloat(0f, (float) Math.PI * 2);
                valueAnimator.setDuration(2000);
                //线性变换插值器
                valueAnimator.setInterpolator(new LinearInterpolator());
                valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        scaleAngle = (float) animation.getAnimatedValue();
                        postInvalidate();
                    }
                });
                valueAnimator.start();
            }
    
            public void cancle() {
                valueAnimator.cancel();
            }
    
            @Override
            public void drawState(Canvas canvas) {
                //绘制背景
                drawBackground(canvas);
                //绘制圆
                drawCircle(canvas);
            }
        }
    
        //聚合状态
        private class MergingState extends SlpashState {
            public MergingState() {
                ValueAnimator valueAnimator = ValueAnimator.ofInt(bigCircleRadius, smallCircleRadius);
                valueAnimator.setDuration(1000);
                //线性变换插值器
                valueAnimator.setInterpolator(new LinearInterpolator());
                valueAnimator.setRepeatCount(0);
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        bigCircleRadius = (int) animation.getAnimatedValue();
                        postInvalidate();
                    }
                });
                valueAnimator.start();
                valueAnimator.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {
    
                    }
    
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        //开始扩散
                        drawState=new ExpandState();
    
                    }
    
                    @Override
                    public void onAnimationCancel(Animator animation) {
    
                    }
    
                    @Override
                    public void onAnimationRepeat(Animator animation) {
    
                    }
                });
            }
    
            @Override
            public void drawState(Canvas canvas) {
                //绘制背景
                drawBackground(canvas);
                //绘制圆
                drawCircle(canvas);
            }
        }
        //扩散状态
        private class ExpandState extends SlpashState {
            private  ValueAnimator valueAnimator;
    
            public ExpandState() {
                valueAnimator = ValueAnimator.ofFloat(0,expandRadius);
                valueAnimator.setDuration(2000);
                //线性变换插值器
                valueAnimator.setInterpolator(new LinearInterpolator());
                valueAnimator.setRepeatCount(0);
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        mPaintExpandMove = (float) animation.getAnimatedValue();
                        postInvalidate();
                    }
                });
                valueAnimator.start();
            }
    
            public void cancle() {
                valueAnimator.cancel();
            }
    
            @Override
            public void drawState(Canvas canvas) {
                //绘制背景
                drawBackground(canvas);
                //绘制圆
               // drawCircle(canvas);
            }
        }
        private void drawCircle(Canvas canvas) {
            for (int i = 0; i < colorsCircle.length; i++) {
                //绘制每个小圆
                mPaintSmallCircle.setColor(colorsCircle[i]);
                //根据勾股定理求出xy的坐标
                float cx = (float) Math.cos(i * angle + scaleAngle) * bigCircleRadius + getWidth() / 2;
                float cy = (float) Math.sin(i * angle + scaleAngle) * bigCircleRadius + getHeight() / 2;
                canvas.drawCircle(cx, cy, smallCircleRadius, mPaintSmallCircle);
            }
        }
    
        private void drawBackground(Canvas canvas) {
            if (drawState instanceof ExpandState){
                Log.d("mPaintExpandMove   ",mPaintExpandMove+"");
                //画笔的宽度=对角线宽度-空心圆的半径
                float strokeWidth=expandRadius-mPaintExpandMove;
                mPaintExpand.setStrokeWidth(strokeWidth);
                //画圆的半径=空心圆的半径+画笔宽度/2
                float radius = mPaintExpandMove + strokeWidth/2;
                canvas.drawCircle(getWidth()/2,getHeight()/2,radius,mPaintExpand);
            }else{
                canvas.drawColor(Color.WHITE);
            }
    
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (drawState == null) {
                drawState = new RotateState();
            }
            drawState.drawState(canvas);
        }
    
    }
    

    相关文章

      网友评论

        本文标题:Android 属性动画+自定义view实现加载动画

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