水波纹+旋转小球动画

实现效果:

水波纹+旋转小球动画_第1张图片

实现思路:

1.首先绘制小圆的位置:
水波纹+旋转小球动画_第2张图片
每个小圆的间隔为: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();
    }
}

你可能感兴趣的:(Android干货分享)