一個簡單的載入動畫(一)

月光邊境發表於2018-01-18

最終效果,這個動畫是在花瓣上看到的,主要是實現動畫, 程式碼還有優化的地方懶得做了。什麼時候用到這個再來封裝下。

一個簡單的載入動畫(一)

    /**
     * 一個簡單的載入動畫
     */
    public class LoadingView extends View {
        /**
         * 三個外圈圓的背景色
         */
        private int leftCircleColor = Color.parseColor("#e83939");
        private int centerColor = Color.parseColor("#70c7d4");
        private int rightColor = Color.parseColor("#FF4081");
        /**
         * 控制元件寬高
         */
        private int mWidth;
        private int mHeight;
        /**
         * 三個外圈圓的半徑和padding
         */
        private int circleRadius;
        private int circlePadding;
        /**
         * 左右圓動畫的最大和最小半徑
         */
        private int leftAndRightMaxRadius;
        private int leftAndRightMinRadius;
        private int leftInsideRadius;
        private int rightInsideRadius;
        /**
         * 中心圓動畫的最大半徑
         */
        private int centerMaxRadius;
        private int centerMinRadius;
        private int centerInsideRadius;
        /**
         * 值動畫是否正在播放
         */
        private boolean animPlaying;

        public LoadingView(Context context) {
            super(context);
            init(null);
        }

        public LoadingView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs);
        }

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

        private void init(AttributeSet attrs) {
            circleRadius = dip2px(15);
            circlePadding = dip2px(50);
            leftAndRightMaxRadius = dip2px(9);
            leftAndRightMinRadius = dip2px(3);
            centerMaxRadius = dip2px(12);
            centerMinRadius = dip2px(6);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (mWidth == 0 || mHeight == 0)
                return;
            //畫左邊外圈
            Paint leftOutSideCircle = new Paint();
            leftOutSideCircle.setColor(leftCircleColor);
            leftOutSideCircle.setAntiAlias(true);
            canvas.drawCircle(mWidth / 2 - circlePadding, mHeight / 2, circleRadius, leftOutSideCircle);
            //畫中心外圈圓
            Paint centerOutSidePaint = new Paint();
            centerOutSidePaint.setAntiAlias(true);
            centerOutSidePaint.setColor(centerColor);
            canvas.drawCircle(mWidth / 2, mHeight / 2, circleRadius, centerOutSidePaint);
            //畫右邊外圈圓
            Paint rightOutSidePaint = new Paint();
            rightOutSidePaint.setColor(rightColor);
            rightOutSidePaint.setAntiAlias(true);
            canvas.drawCircle(mWidth / 2 + circlePadding, mHeight / 2, circleRadius, rightOutSidePaint);
            //值動畫播放完成繼續開始重新播放
            if (!animPlaying) {
                startAnim();
                animPlaying = true;
            }
            //左邊中心圓
            Paint leftInSideCircle = new Paint();
            leftInSideCircle.setColor(Color.WHITE);
            leftInSideCircle.setAntiAlias(true);
            canvas.drawCircle(mWidth / 2 - circlePadding, mHeight / 2, leftInsideRadius, leftInSideCircle);
            //中間中心圓
            Paint centerInSidePaint = new Paint();
            centerInSidePaint.setAntiAlias(true);
            centerInSidePaint.setColor(Color.WHITE);
            canvas.drawCircle(mWidth / 2, mHeight / 2, centerInsideRadius, centerInSidePaint);
            //右邊中心圓
            Paint rightInSidePaint = new Paint();
            rightInSidePaint.setColor(Color.WHITE);
            rightInSidePaint.setAntiAlias(true);
            canvas.drawCircle(mWidth / 2 + circlePadding, mHeight / 2, rightInsideRadius, rightInSidePaint);
        }

        private void startAnim() {
            final ValueAnimator mValueAnim = ValueAnimator.ofInt(1);
            mValueAnim.setInterpolator(new LinearInterpolator());
            mValueAnim.setDuration(800);
            mValueAnim.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {
                }

                @Override
                public void onAnimationEnd(Animator animator) {
                    int tempA = centerMinRadius;
                    centerMinRadius = centerMaxRadius;
                    centerMaxRadius = tempA;
                    int tempB = leftAndRightMaxRadius;
                    leftAndRightMaxRadius = leftAndRightMinRadius;
                    leftAndRightMinRadius = tempB;
                    animPlaying = false;
                    invalidate();
                }

                @Override
                public void onAnimationCancel(Animator animator) {
                }

                @Override
                public void onAnimationRepeat(Animator animator) {
                }
            });
            mValueAnim.setRepeatMode(ValueAnimator.RESTART);
            mValueAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float fraction = mValueAnim.getAnimatedFraction();
                    centerInsideRadius = evaluate(fraction, centerMaxRadius, centerMinRadius);
                    leftInsideRadius = evaluate(fraction, leftAndRightMinRadius, leftAndRightMaxRadius);
                    rightInsideRadius = evaluate(fraction, leftAndRightMaxRadius, leftAndRightMinRadius);
                    Log.i("===TAG===", "centerInsideRadius-" + centerInsideRadius + "leftInsideRadius-" + leftInsideRadius + "rightInsideRadius-" + rightInsideRadius);
                    invalidate();
                }
            });
            mValueAnim.start();
        }

        public int evaluate(float fraction, int startValue, int endValue) {
            return (int) (startValue + fraction * (endValue - startValue));
        }

        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mWidth = w;
            mHeight = h;
        }

        public int dip2px(float dpValue) {
            final float scale = getContext().getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    }
複製程式碼

相關文章