水波紋+旋轉小球動畫

實現效果:

這裏寫圖片描述

實現思路:

1.首先繪製小圓的位置:
這裏寫圖片描述
每個小圓的間隔爲:2 * Math.PI / CIRCLE_COUNT
2.通過控制第一個小圓的角度變化,控制小圓的旋轉。
通過控制大圓半徑,實現小圓的聚合
3.水波紋實現:繪製一個空心圓,通過不斷改變空心圓的半徑和畫筆寬度。

代碼實現:

package com.test.paintdemo;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;

/**
 * Created by ygdx_lk on 17/6/26.
 */

public class RingStartLoading extends View {

    private final Paint mPaint;
    private final LinearGradient linearGradient;
    private int width, height;//控件寬,高
    private double diagonal;//對角線長度
    private final int CIRCLE_COUNT = 6;
    private final int RADIUS = 100;//大圓半徑
    private float radius = RADIUS;//大圓半徑
    private final int RADIUS_SMALL = 20;//小圓半徑
    private final int[] COLORS = {Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW};
    private float startAngle = 0;//起始角度
    private static final String TAG = "RingStartLoading";
    private boolean waterRippleStart;

    public RingStartLoading(Context context) {
        super(context);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        linearGradient = new LinearGradient(0, 0, 200, 200, COLORS, null, Shader.TileMode.MIRROR);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //畫布平移到屏幕中心點
        canvas.translate(width / 2, height / 2);
        mPaint.reset();
        mPaint.setAntiAlias(true);


        if(waterRippleStart){
            //繪製水波紋效果
            drawWaterRipple(canvas);
        }

        if(radius <= RADIUS) {
            //繪製圓
            drawCircles(canvas);
        }


    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                startAnim();
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
        //計算屏幕對角線長度
        diagonal = Math.ceil(Math.sqrt(w * w + h * h));
    }

    //繪製水波紋
    private void drawWaterRipple(Canvas canvas) {
        //繪製背景
        mPaint.setStrokeWidth(1);
        mPaint.setShader(linearGradient);
        canvas.drawRect(-width/2, -height/2, width/2, height/2, mPaint);
        mPaint.setShader(null);

        //得到畫筆的寬度
        float strokeWidth = (float) (diagonal / 2 - radius);
        mPaint.setStrokeWidth(strokeWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.WHITE);
        //畫圓的半徑 = radius + 畫筆寬度/2
        float waterRippleRadius = radius + strokeWidth / 2;
        canvas.drawCircle(0, 0, waterRippleRadius, mPaint);
    }

    //繪製CIRCLE_COUNT個圓
    private void drawCircles(Canvas canvas) {
        //計算相鄰圓的角度
        double angle = 2 * Math.PI / CIRCLE_COUNT;
        mPaint.setStrokeWidth(1);
        mPaint.setStyle(Paint.Style.FILL);
        //繪製圓
        for (int i = 0; i < CIRCLE_COUNT; i++) {
            float x = (float) (radius * Math.cos(startAngle + angle * i));//計算圓心x座標
            float y = (float) (radius * Math.sin(startAngle + angle * i));//計算圓心y座標
            mPaint.setColor(COLORS[i % COLORS.length]);
            canvas.drawCircle(x, y, RADIUS_SMALL, mPaint);
        }
    }

    //啓動動畫
    private void startAnim(){
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, (float)(Math.PI * 2));
        valueAnimator.setDuration(2000);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                startAngle = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });

        final ValueAnimator radiusAnimator = ValueAnimator.ofFloat(RADIUS, 0);
        radiusAnimator.setDuration(2000);
        radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                radius = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });


        ValueAnimator waterRippleAnimator = ValueAnimator.ofFloat(0, (float)diagonal / 2);
        waterRippleAnimator.setDuration(4000);
        waterRippleAnimator.setInterpolator(new LinearInterpolator());
        waterRippleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                waterRippleStart = true;
                radius = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playSequentially(valueAnimator, radiusAnimator, waterRippleAnimator);
        animatorSet.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                radius = RADIUS;
                waterRippleStart = false;
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                animation.start();
            }
        });
        animatorSet.start();
    }
}
發佈了101 篇原創文章 · 獲贊 29 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章