1.效果图
![d1df3ad7517a872fb8409b403b3a0bfe.png](https://i-blog.csdnimg.cn/blog_migrate/4767a8ce5fd5a4af214f0449972adcfb.jpeg)
![a24ab6552c8e13824f7b956d428bb97e.png](https://i-blog.csdnimg.cn/blog_migrate/1673313b24b9552af878e183315f0385.jpeg)
![91bff312480f75352f8da82fa030bc42.png](https://i-blog.csdnimg.cn/blog_migrate/88ba46bdf64e6427396b10687dfa607e.jpeg)
![a5701e10921ba5cdc4c3ac7449c205e1.png](https://i-blog.csdnimg.cn/blog_migrate/de178dd226b42a3b8e993f1a079457db.png)
![440c1286d57744a70ebfef19735136b1.png](https://i-blog.csdnimg.cn/blog_migrate/c359e98c18b2a79550c7dd29adc56568.png)
![5395361019c125900d2556c26d8bf41a.png](https://i-blog.csdnimg.cn/blog_migrate/092afa6180e0fbacf766a17f8a9b6227.png)
2.从上面动图可以看到动画一共分类三个
a旋转动画
b聚合动画(及先变大后缩小动画)
c水波纹动画
3.实现步骤:
3.1.初始化画笔和颜色数组
private void init(Context context) { //对两只画笔初始化 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mHolePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mHolePaint.setStyle(Paint.Style.STROKE); mHolePaint.setColor(mBackgroundColor); //对颜色数组初始化 mCircleColors = context.getResources().getIntArray(R.array.splash_circle_colors); }
3.2.在onSizeChanged中获取旋转圆的中心坐标以及扩散圆的最大半径
//获取旋转圆的中心坐标 mCenterX = w * 1f / 2; mCenterY = h * 1f / 2; //获取扩散圆最大的半径 mDistance = (float) (Math.hypot(w, h) / 2);
3.3.开始绘制
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //开始绘制 if (mState == null) { mState = new mSplashView.RotateState(); } mState.drawState(canvas); }
3.4.建一个抽象类让其子类调用
private mSplashState mState; private abstract class mSplashState {//抽象类 abstract void drawState(Canvas canvas); }
3.5.旋转动画的实现
private class RotateState extends mSplashState { //属性动画执行 private RotateState(){ //旋转一周 mValueAnimator = ValueAnimator.ofFloat(0,(float) (Math.PI*2)); //执行两遍 mValueAnimator.setRepeatCount(2); mValueAnimator.setDuration(mRotateDuration); //设置差值器 mValueAnimator.setInterpolator(new LinearInterpolator()); //监听动画的更新状态 mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //当前的旋转角度 mCurrentRotateAngle = (float) animation.getAnimatedValue(); //使得onDraw方法重新执行 invalidate(); } }); //监听动画的执行状态 mValueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); //结束的时候调用聚合动画 mState = new MerginState(); } }); mValueAnimator.start(); } @Override void drawState(Canvas canvas) { //绘制背景 drawBackground(canvas); //绘制6个小球 drawCircles(canvas); } }
3.6.聚合动画的实现(即先放大后缩小)
//2聚合动画 private class MerginState extends mSplashState{ //执行聚合动画 private MerginState(){ mValueAnimator = ValueAnimator.ofFloat(mCircleRadius, mRotateRadius); mValueAnimator.setDuration(mRotateDuration); mValueAnimator.setInterpolator(new OvershootInterpolator(10f)); mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mCurrentRotateRadius = (float) animation.getAnimatedValue(); invalidate(); } }); mValueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mState = new ExpandState(); } }); mValueAnimator.reverse(); } @Override void drawState(Canvas canvas) { //绘制背景 drawBackground(canvas); //绘制6个小球 drawCircles(canvas); } }
3.7.水波纹动画的实现
//3.水波纹 private class ExpandState extends mSplashState { public ExpandState() { mValueAnimator = ValueAnimator.ofFloat(mCircleRadius, mDistance); // mValueAnimator.setRepeatCount(2); mValueAnimator.setDuration(mRotateDuration); mValueAnimator.setInterpolator(new LinearInterpolator()); mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mCurrentHoleRadius = (float) animation.getAnimatedValue(); invalidate(); } }); mValueAnimator.start(); } @Override void drawState(Canvas canvas) { drawBackground(canvas); } }
3.8.绘制圆和绘制 背景的方法实现
private void drawBackground(Canvas canvas) { if (mCurrentHoleRadius > 0){ //绘制空心圆 float strokeWidth = mDistance - mCurrentHoleRadius; float radius = strokeWidth / 2 + mCurrentHoleRadius; mHolePaint.setStrokeWidth(strokeWidth); canvas.drawCircle(mCenterX,mCenterY, radius, mHolePaint); }else{ canvas.drawColor(mBackgroundColor); } } private void drawCircles(Canvas canvas) { //计算两个小球之间的角度 float rotateAngle = (float) (Math.PI * 2 / mCircleColors.length); for (int i = 0; i < mCircleColors.length; i++) { float angle = i * rotateAngle + mCurrentRotateAngle; float cx = (float) (Math.cos(angle) * mCurrentRotateRadius + mCenterX); float cy = (float) (Math.sin(angle) * mCurrentRotateRadius + mCenterY); mPaint.setColor(mCircleColors[i]); canvas.drawCircle(cx, cy, mCircleRadius, mPaint); } }
喜欢的可以点个关注,后面会持续更新Android新技术,但愿人长久,搬砖不再有。