Android简单炫酷SplashView

参考:
https://www.jianshu.com/p/6dd6c89220d9

https://blog.csdn.net/u010008118/article/details/103070847

https://blog.csdn.net/u014133119/article/details/80998025

效果展示

在这里插入图片描述

绘制六个圆

1 初始化

在colors.xml中添加6个颜色

    <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>

初始化颜色和画笔

  	// 小圆圈的颜色列表,在initialize方法里面初始化
    private int[] mCircleColors;
    // 绘制圆的画笔
    private Paint mPaint = new Paint();

    public SplashView(Context context) {
        super(context);
        init(context);
    }
    private void init(Context context) {
        mCircleColors = context.getResources().getIntArray(R.array.splash_circle_colors);
        //消除锯齿
        mPaint.setAntiAlias(true);
    }

确定屏幕中心点坐标

    // 屏幕正中心点坐标
    private float mCenterX;
    private float mCenterY;
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mCenterX = w / 2f;
        mCenterY = h / 2f;
    }

2 绘制六个小圆

mCircleColors这里一共是6中颜色,分别对应6个小圆颜色
小圆间隔角度= 2π/小圆的个数
当前小圆的角度 = i * 间隔角度
当前小圆的 x坐标 = 小圆半径cos(a) + 小圆心X坐标
当前小圆的 y坐标 = 小圆半径
sin(a) + 小圆心Y坐标

    // 大圆(里面包含很多小圆的)的半径
    private float mRotationRadius = 90;
    // 每一个小圆的半径
    private float mCircleRadius = 18;
    //当前大圆的半径
    private float mCurrentRotationRadius = mRotationRadius;

 	@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawCircles(canvas);
    }

    private void drawCircles(Canvas canvas) {
        //每个小圆之间的间隔角度= 2π /  小圆的个数
        float rotetionAngle = (float) (2 * Math.PI / mCircleColors.length);
        for (int i = 0; i < mCircleColors.length; i++) {
            /**
             * x= r* cos(a) + centerX
             * y = r* sin(a) + centerY
             */
            double angle = i * rotetionAngle ;
            float cx = (float) (mCurrentRotationRadius * Math.cos(angle) + mCenterX);
            float cy = (float) (mCurrentRotationRadius * Math.sin(angle) + mCenterY);
            mPaint.setColor(mCircleColors[i]);
            canvas.drawCircle(cx, cy, mCircleRadius, mPaint);
        }
    }

在这里插入图片描述

动画

  • 刚进来时执行旋转动画
  • 数据加载完毕之后调用聚合逃逸动画
  • 聚合逃逸动画完成之后,进行扩散

使用策略模式控制状态转变,一种状态控制一个动画

    /**
     * 策略模式(状态模式),每一种状态是一个绘制
     */
    private abstract class SplashState {
        public abstract void drawState(Canvas canvas);

        public void cancle() {

        }
    }

    /**
     * 旋转动画
     */
    private class RotateState extends SplashState {

        @Override
        public void drawState(Canvas canvas) {

        }
    }

    /**
     * 聚合动画
     */
    private class MerginState extends SplashState {

        @Override
        public void drawState(Canvas canvas) {

        }
    }

    /**
     * 扩散动画
     */
    private class ExpandState extends SplashState {

        @Override
        public void drawState(Canvas canvas) {

        }
    }
    //1、旋转动画
    private class RotateState extends SplashState {
        public RotateState() {
            //1、动画的初始化工作,2、开启动画
            mAnimator = ValueAnimator.ofFloat(0f, (float) Math.PI * 2);
            mAnimator.setInterpolator(new LinearInterpolator());
            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    mCurrentRotationAngle = (float) valueAnimator.getAnimatedValue();
                    postInvalidate();
                }
            });
            mAnimator.setDuration(mRotationDuration);
            //无限循环
            mAnimator.setRepeatCount(ValueAnimator.INFINITE);
            mAnimator.start();
        }

        @Override
        public void drawState(Canvas canvas) {
            //背景
            drawBackground(canvas);
            //绘制小圆
            drawCircles(canvas);
        }
    }
    //执行聚合动画
    public void splashDisappear() {
        if (mState != null && mState instanceof RotateState) {
            RotateState rotateState = (RotateState) mState;
            rotateState.cencel();
            post(new Runnable() {
                @Override
                public void run() {
                    mState = new MergingState();
                }
            });
        }
    }
    //2、聚合动画
    private class MergingState extends SplashState {
        public MergingState() {
            mAnimator = ValueAnimator.ofFloat(0f, mRotationRadius);
            mAnimator.setDuration(mRotationDuration);
            mAnimator.setInterpolator(new OvershootInterpolator(10f));// 向前甩一定值后再回到原来位置
            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    mCurrentRotationRadius = (float) valueAnimator.getAnimatedValue();
                    invalidate();
                }
            });
            mAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    mState = new ExpandState();
                }
            });
            //反转
            mAnimator.reverse();
        }

        @Override
        public void drawState(Canvas canvas) {
            //背景
            drawBackground(canvas);
            //绘制小圆
            drawCircles(canvas);
        }
    }
    //3、水波纹扩散动画
    private class ExpandState extends SplashState {
        public ExpandState() {
            mAnimator = ValueAnimator.ofFloat(mCircleRadius, mDiagonalDist);
            mAnimator.setDuration(mRotationDuration);
            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    mHoleRadius = (float) valueAnimator.getAnimatedValue();
                    invalidate();
                }
            });
            mAnimator.start();

        }

        @Override
        public void drawState(Canvas canvas) {
            drawBackground(canvas);
        }
    }
public class MainActivity extends AppCompatActivity {

    private SplashView splashView;
    private FrameLayout mMainView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mMainView = new FrameLayout(this);
        ContentView contentView = new ContentView(this);
        mMainView.addView(contentView);
        splashView = new SplashView(this);
        mMainView.addView(splashView);
        setContentView(mMainView);
        startLoaddData();
    }

    private void startLoaddData() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //表示数据加载完毕,进入第二个状态
                splashView.splashDisappear();
            }
        }, 3000);//延时时间
    }
}

Github:https://github.com/345166018/AndroidUI/tree/master/HxSplashView

发布了383 篇原创文章 · 获赞 54 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/hongxue8888/article/details/104010485