加载超炫动画
1、MainActivity
1 package com.zyhui.zyh_splash; 2 3 import android.os.Bundle; 4 import android.os.Handler; 5 import android.widget.FrameLayout; 6 import android.app.Activity; 7 8 public class MainActivity extends Activity { 9 10 private FrameLayout mMainView; 11 private SplashView sv; 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 17 mMainView = new FrameLayout(this); 18 19 ContentView mContentView = new ContentView(this); 20 mMainView.addView(mContentView); 21 22 sv = new SplashView(this); 23 mMainView.addView(sv); 24 25 setContentView(mMainView); 26 27 //模拟后台加载数据 28 startLoadData(); 29 } 30 31 Handler handler = new Handler(); 32 private void startLoadData() { 33 handler.postDelayed(new Runnable(){ 34 @Override 35 public void run() { 36 //数据加载 37 38 //数据加载完后,加载后面的两个动画 39 sv.splashAndDisapper(); 40 } 41 42 }, 20000); 43 } 44 45 46 }
2、ContentView
1 package com.zyhui.zyh_splash; 2 3 import android.content.Context; 4 import android.widget.ImageView; 5 6 public class ContentView extends ImageView { 7 8 public ContentView(Context context) { 9 super(context); 10 setImageResource(R.drawable.spring); 11 } 12 13 }
3、动画视图类
1 package com.zyhui.zyh_splash; 2 3 import android.animation.Animator; 4 import android.animation.AnimatorListenerAdapter; 5 import android.animation.ValueAnimator; 6 import android.animation.ValueAnimator.AnimatorUpdateListener; 7 import android.content.Context; 8 import android.graphics.Canvas; 9 import android.graphics.Color; 10 import android.graphics.Paint; 11 import android.graphics.Paint.Style; 12 import android.view.View; 13 import android.view.animation.LinearInterpolator; 14 import android.view.animation.OvershootInterpolator; 15 16 //======================================= 17 //1、问题:为什么第三个动画后,可以看到第底层图片? 18 // 答:它没有调用drawbackground方法 19 //2、问:动画是如何衔接的? 20 // 答:动画是通过invalidate()方法进行重绘操作的 21 //3、关于post方法的参考: 22 // 答:http://www.cnblogs.com/akira90/archive/2013/03/06/2946740.html 23 //======================================= 24 public class SplashView extends View { 25 26 //大圆半径 27 private float mRotationRadius = 90; 28 //小圆半径 29 private float mCircleRadius = 18; 30 //小圆圈的颜色列表 31 private int[] mCircleColors; 32 //大圆和小圆旋转的时间,可以控制旋转速度 33 private long mRotationDuration = 3200;//ms 34 //第二部分动画执行的总时间(各占1/3) 35 private long mSplashDuration = 3200; //ms 36 //整体的背景颜色 37 private int mSplashBgColor = Color.WHITE; 38 39 //空心圆初始半径 40 private float mHoleRadius = 0F; 41 //当前大圆旋转的角度 42 private float mCurrentRotationAngle = 0F; 43 //当前大圆半径 44 private float mCurrentRotationRadius = mRotationRadius; 45 46 //绘制圆的画笔 47 private Paint mPaint = new Paint(); 48 //绘制背景画笔 49 private Paint mPaintBackground = new Paint(); 50 51 //屏幕正中心坐标 52 private float mCenterX; 53 private float mCenterY; 54 //屏幕对角线一半 55 private float mDiagonalDist; 56 57 //保存当前动画状态 58 private SplashState mState = null; 59 private abstract class SplashState{ 60 public abstract void drawState(Canvas canvas); 61 } 62 63 public SplashView(Context context) { 64 super(context); 65 init(context); 66 } 67 68 private void init(Context context) { 69 mCircleColors = context.getResources().getIntArray(R.array.splash_circle_colors); 70 71 //设置画笔 72 mPaint.setAntiAlias(true);//设置取消锯齿 73 mPaintBackground.setAntiAlias(true); 74 //设置边框样式 75 mPaintBackground.setStyle(Style.STROKE); 76 mPaintBackground.setColor(mSplashBgColor); 77 } 78 79 @Override 80 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 81 // TODO Auto-generated method stub 82 super.onSizeChanged(w, h, oldw, oldh); 83 mCenterX = w/2f; 84 mCenterY = h/2f; 85 mDiagonalDist = (float) (Math.sqrt(w*w+h*h)/2); 86 } 87 @Override 88 protected void onDraw(Canvas canvas) { 89 if(mState == null){ 90 mState = new RotationState(); 91 } 92 mState.drawState(canvas); 93 super.onDraw(canvas); 94 } 95 96 //数据加载完之后,加载后面的两个动画 97 public void splashAndDisapper(){ 98 if(mState != null && mState instanceof RotationState){ 99 RotationState rs = (RotationState) mState; 100 rs.cancel();//取消第一个动画 101 post(new Runnable(){ 102 @Override 103 public void run() { 104 mState = new MergingState(); 105 } 106 107 }); 108 } 109 } 110 111 //旋转类 112 private class RotationState extends SplashState{ 113 private ValueAnimator mAnimator; 114 public RotationState(){ 115 //小圆半径,需要大圆半径和它旋转的角度 116 //估值器--它使用的是弧度0~2PI 117 mAnimator = ValueAnimator.ofFloat(0, (float)Math.PI*2); 118 //线性插值器,会平滑地计算;这样在每完成一个周期时,它不会卡顿 119 mAnimator.setInterpolator(new LinearInterpolator()); 120 mAnimator.setDuration(mRotationDuration);//设置旋转时间 121 mAnimator.addUpdateListener(new AnimatorUpdateListener() { 122 @Override 123 public void onAnimationUpdate(ValueAnimator animation) { 124 //这个mCurrentRotationAngle这个值的变化,就是造成小圆旋转的原因;若 125 //这个值不变了,则小圆们就不会旋转 126 mCurrentRotationAngle = (Float)animation.getAnimatedValue(); 127 //提醒view重绘 128 invalidate(); 129 } 130 }); 131 132 //设置旋转次数--无穷次数;因为它不知道什么时候进入下一个动画,所以把它设置为重复次数为无穷 133 mAnimator.setRepeatCount(ValueAnimator.INFINITE); 134 mAnimator.start(); 135 } 136 137 @Override 138 public void drawState(Canvas canvas) { 139 //实现动画的绘制 140 //1、清空背景 141 drawBackground(canvas); 142 //绘制小圆 143 drawCircle(canvas); 144 } 145 146 //取消该动画 147 public void cancel(){ 148 mAnimator.cancel(); 149 } 150 151 } 152 153 //聚合动画 154 private class MergingState extends SplashState{ 155 private ValueAnimator mAnimator; 156 public MergingState(){ 157 //小圆半径,需要大圆半径和它旋转的角度 158 //估值器 159 mAnimator = ValueAnimator.ofFloat(0,mRotationRadius); 160 //插值器-弹射效果的 161 mAnimator.setInterpolator(new OvershootInterpolator(6f)); 162 mAnimator.setDuration(mSplashDuration/3);//设置动画时间 163 mAnimator.addUpdateListener(new AnimatorUpdateListener() { 164 @Override 165 public void onAnimationUpdate(ValueAnimator animation) { 166 mCurrentRotationRadius = (Float)animation.getAnimatedValue(); 167 //提醒view重绘 168 invalidate(); 169 } 170 }); 171 172 //监听动画执行完毕状态 173 mAnimator.addListener(new AnimatorListenerAdapter() { 174 @Override 175 public void onAnimationEnd(Animator animation) { 176 super.onAnimationEnd(animation); 177 //进入下一个动画 178 mState = new ExpandingState(); 179 } 180 }); 181 //动画反转过来 182 mAnimator.reverse(); 183 } 184 185 @Override 186 public void drawState(Canvas canvas) { 187 //实现动画的绘制 188 //1、清空背景 189 drawBackground(canvas); 190 //绘制小圆 191 drawCircle(canvas); 192 } 193 194 } 195 196 //扩散动画 197 private class ExpandingState extends SplashState{ 198 private ValueAnimator mAnimator; 199 public ExpandingState(){ 200 //估值器 --空心圆的半径:0到对角线的一半 201 mAnimator = ValueAnimator.ofFloat(0,mDiagonalDist); 202 //插值器-弹射效果的 203 //mAnimator.setInterpolator(new OvershootInterpolator(6f)); 204 mAnimator.setDuration(mSplashDuration/3);//设置动画时间 205 mAnimator.addUpdateListener(new AnimatorUpdateListener() { 206 @Override 207 public void onAnimationUpdate(ValueAnimator animation) { 208 //空心圆半径 209 mHoleRadius = (Float)animation.getAnimatedValue(); 210 //提醒view重绘 211 invalidate(); 212 } 213 }); 214 215 216 mAnimator.start(); 217 } 218 219 @Override 220 public void drawState(Canvas canvas) { 221 //1、清空背景 222 //drawBackground(canvas); 223 //绘制空心圆效果 224 if(mHoleRadius > 0f){ 225 //画笔的宽度:对角线的一半 - 空心圆半径 226 float storkeWidth = mDiagonalDist - mHoleRadius; 227 mPaintBackground.setStrokeWidth(storkeWidth); 228 229 float circleRadius = mHoleRadius + mDiagonalDist / 2f; 230 canvas.drawCircle(mCenterX, mCenterY, circleRadius, mPaintBackground); 231 } 232 } 233 234 } 235 236 //清空画布 237 public void drawBackground(Canvas canvas) { 238 canvas.drawColor(mSplashBgColor); 239 } 240 241 //画多个小圆 242 public void drawCircle(Canvas canvas) { 243 //每个小圆的间隔角度 244 float rotationAngle = (float) (Math.PI*2/mCircleColors.length); 245 246 for(int i=0; i<mCircleColors.length; i++){ 247 double angle = mCurrentRotationAngle + i * rotationAngle; 248 float cx = (float) (mCenterX + mCurrentRotationRadius * Math.cos(angle)); 249 float cy = (float) (mCenterY + mCurrentRotationRadius * Math.sin(angle)); 250 mPaint.setColor(mCircleColors[i]); 251 canvas.drawCircle(cx, cy, mCircleRadius, mPaint); 252 } 253 } 254 255 }
4、颜色值,使用xml进行配置
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 <color name="splash_bg">#F8F6EC</color> 4 <color name="orange">#FF9600</color> 5 <color name="aqua">#02D1AC</color> 6 <color name="yellow">#FFD200</color> 7 <color name="blue">#00C6FF</color> 8 <color name="green">#00E099</color> 9 <color name="pink">#FF3892</color> 10 11 <array name="splash_circle_colors"> 12 <item>@color/blue</item> 13 <item>@color/green</item> 14 <item>@color/pink</item> 15 <item>@color/orange</item> 16 <item>@color/aqua</item> 17 <item>@color/yellow</item> 18 </array> 19 </resources>
注:onSizeChanged在什么时候执行呢?可看http://blog.csdn.net/jason0539/article/details/9896743

浙公网安备 33010602011771号