Android加載動畫系列——GearsLoadingAnim
Ios系統每次升級的時候,界面上的齒輪圖標都會轉動,今天就讓我們來探索一下這個效果是怎麼實現的吧~
讓我們先來看看效果圖:
1、GearsLoadingAnim.java源碼如下:
public class GearsLoadingAnim extends View { private float mWidth = 0f; private Paint mPaint, mPaintWheelBig, mPaintWheelSmall, mPaintAxle, mPaintCenter; private float mPadding = 0f; private float mPaintCenterRadius; private float mWheelSmallLength, mWheelBigLength; private int mWheelSmallSpace = 8; private int mWheelBigSpace = 6; ValueAnimator valueAnimator = null; float mAnimatedValue = 0f; public GearsLoadingAnim(Context context) { this(context, null); } public GearsLoadingAnim(Context context, AttributeSet attrs) { this(context, attrs, 0); } public GearsLoadingAnim(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initPaint(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (getMeasuredWidth() > getHeight()) { mWidth = getMeasuredHeight(); } else { mWidth = getMeasuredWidth(); } } private void drawCircle(Canvas canvas) { canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2 - mPadding, mPaint); canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 4, mPaint); } private void drawAxleAndCenter(Canvas canvas) { for (int i = 0; i < 3; i++) { float x2 = (float) ((mWidth / 2.f - mPadding) * Math.cos(i * (360 / 3) * Math.PI / 180f)); float y2 = (float) ((mWidth / 2.f - mPadding) * Math.sin(i * (360 / 3) * Math.PI / 180f)); float x = (float) (mPaintCenterRadius * Math.cos(i * (360 / 3) * Math.PI / 180f)); float y = (float) (mPaintCenterRadius * Math.sin(i * (360 / 3) * Math.PI / 180f)); canvas.drawLine(mWidth / 2 - x, mWidth / 2 - y, mWidth / 2 - x2, mWidth / 2 - y2, mPaintAxle); } canvas.drawCircle(mWidth / 2, mWidth / 2, mPaintCenterRadius, mPaintCenter); } private void drawWheelBig(Canvas canvas) { for (int i = 0; i < 360; i++) { int angle = (int) (mAnimatedValue * mWheelBigSpace + i);//順時針 float x = (float) ((mWidth / 2.f - mPadding + mWheelBigLength) * Math.cos(angle * Math.PI / 180f)); float y = (float) ((mWidth / 2.f - mPadding + mWheelBigLength) * Math.sin(angle * Math.PI / 180f)); float x2 = (float) ((mWidth / 2.f - mPadding) * Math.cos(angle * Math.PI / 180f)); float y2 = (float) ((mWidth / 2.f - mPadding) * Math.sin(angle * Math.PI / 180f)); canvas.drawLine(mWidth / 2.f - x, mWidth / 2.f - y, mWidth / 2.f - x2, mWidth / 2.f - y2, mPaintWheelBig); } } private void drawWheelSmall(Canvas canvas) { for (int i = 0; i < 360; i = i + mWheelSmallSpace) { int angle = (int) (360 - mAnimatedValue * mWheelBigSpace + i); float x = (float) ((mWidth / 4.f) * Math.cos(angle * Math.PI / 180f)); float y = (float) ((mWidth / 4.f) * Math.sin(angle * Math.PI / 180f)); float x2 = (float) ((mWidth / 4.f + mWheelSmallSpace) * Math.cos(angle * Math.PI / 180f)); float y2 = (float) ((mWidth / 4.f + mWheelSmallSpace) * Math.sin(angle * Math.PI / 180f)); canvas.drawLine(mWidth / 2.f - x, mWidth / 2.f - y, mWidth / 2.f - x2, mWidth / 2.f - y2, mPaintWheelSmall); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); drawCircle(canvas); drawWheelBig(canvas); drawWheelSmall(canvas); drawAxleAndCenter(canvas); canvas.restore(); } public int dip2px(float dpValue) { final float scale = getContext().getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } private void initPaint() { mPaintCenterRadius = dip2px(2.5f) / 2; mPaintCenter = new Paint(); mPaintCenter.setAntiAlias(true); mPaintCenter.setStyle(Paint.Style.STROKE); mPaintCenter.setColor(Color.WHITE); mPaintCenter.setStrokeWidth(dip2px(0.5f)); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.WHITE); mPaint.setStrokeWidth(dip2px(2)); mPaintAxle = new Paint(); mPaintAxle.setAntiAlias(true); mPaintAxle.setStyle(Paint.Style.STROKE); mPaintAxle.setColor(Color.WHITE); mPaintAxle.setStrokeWidth(dip2px(2f)); mPaintWheelBig = new Paint(); mPaintWheelBig.setAntiAlias(true); mPaintWheelBig.setStyle(Paint.Style.STROKE); mPaintWheelBig.setColor(Color.WHITE); mPaintWheelBig.setStrokeWidth(dip2px(1)); mPaintWheelSmall = new Paint(); mPaintWheelSmall.setAntiAlias(true); mPaintWheelSmall.setStyle(Paint.Style.STROKE); mPaintWheelSmall.setColor(Color.WHITE); mPaintWheelSmall.setStrokeWidth(dip2px(0.5f)); mPadding = dip2px(5); mWheelSmallLength = dip2px(3); mWheelBigLength = dip2px(2.5f); } private ValueAnimator startViewAnim(int startF, final int endF, long time) { valueAnimator = ValueAnimator.ofInt(startF, endF); valueAnimator.setDuration(time); valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.setRepeatCount(ValueAnimator.INFINITE); valueAnimator.setRepeatMode(ValueAnimator.RESTART); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mAnimatedValue = (int) valueAnimator.getAnimatedValue(); mAnimatedValue = mAnimatedValue / 100f; postInvalidate(); } }); valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); } @Override public void onAnimationRepeat(Animator animation) { super.onAnimationRepeat(animation); } @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); } }); if (!valueAnimator.isRunning()) { valueAnimator.start(); } return valueAnimator; } public void stopAnim() { if (valueAnimator != null) { clearAnimation(); valueAnimator.setRepeatCount(0); valueAnimator.cancel(); valueAnimator.end(); postInvalidate(); } } public void startAnim() { stopAnim(); startViewAnim(1, 100, 300); } }
2、接着在layout佈局文件中使用我們自定義的動畫控件
<com.cyril.loadinganim.GearsLoadingAnim android:id="@+id/gearloading" android:layout_width="50dp" android:layout_height="50dp" android:visibility="gone" />
3、然後在Activity中實現動畫的播放和停止,使用事例如下:
gearsLoadingAnim = (GearsLoadingAnim) findViewById(R.id.gearloading); gearsLoadingAnim.startAnim();
4、 戳這裏,小編帶你去源碼的下載地址:http://download.csdn.net/detail/zhimingshangyan/9582830