最终效果图:
代码:
public class PointerLoadingView extends View { /** * 外圈圆心宽度 */ private int ringWidth = dip2px(6); /** * 圆心和圆环的颜色 */ private int primaryColor = Color.parseColor("#4b546a"); /** * 指针的颜色 */ private int pointerColor = Color.parseColor("#70c7d4"); /** * 大圆心半径 */ private int bigCircleRadius = dip2px(10); /** * 小圆心的半径 */ private int smallCircleRadius = dip2px(5); /** * 指针转动角度 */ private int pointerAngle = 0; /** * 圆弧的转动半径 */ private int arcAngle = 45; /** * 正方形控件的尺寸 */ private int mSquareSize; public PointerLoadingView(Context context) { super(context); init(); } public PointerLoadingView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public PointerLoadingView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } Paint bigCirclePaint; Paint smallCirclePaint; Paint ringPaint; Paint pointerPaint; Paint arcPaint; Path path; private void init() { //大圆心画笔 bigCirclePaint = new Paint(); bigCirclePaint.setAntiAlias(true); bigCirclePaint.setColor(pointerColor); //小圆心画笔 smallCirclePaint = new Paint(); smallCirclePaint.setAntiAlias(true); smallCirclePaint.setColor(primaryColor); //圆环画笔 ringPaint = new Paint(); ringPaint.setAntiAlias(true); ringPaint.setStyle(Paint.Style.STROKE); ringPaint.setStrokeWidth(ringWidth); ringPaint.setColor(primaryColor); //圆弧画笔 arcPaint = new Paint(); arcPaint.setAntiAlias(true); arcPaint.setStyle(Paint.Style.STROKE); arcPaint.setStrokeWidth(ringWidth); arcPaint.setStrokeCap(Paint.Cap.ROUND); arcPaint.setColor(pointerColor); //指针画笔 pointerPaint = new Paint(); pointerPaint.setAntiAlias(true); pointerPaint.setStyle(Paint.Style.FILL); pointerPaint.setColor(pointerColor); path = new Path(); } /** * 动画是否在播放 */ private boolean animPlaying = false; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mSquareSize == 0) return; canvas.save(); //画三角指针 canvas.translate(mSquareSize / 2, mSquareSize / 2); canvas.rotate(pointerAngle); path.moveTo(-smallCircleRadius - 1, 0); path.lineTo(0, -mSquareSize / 2 + 15); path.lineTo(smallCircleRadius + 1, 0); canvas.drawPath(path, pointerPaint); //画大圆心 canvas.drawCircle(0, 0, bigCircleRadius, bigCirclePaint); //画圆环 canvas.drawCircle(0, 0, mSquareSize / 2 - 10, ringPaint); //画小圆心 canvas.drawCircle(0, 0, smallCircleRadius, smallCirclePaint); //画圆弧 RectF rectF = new RectF(-mSquareSize / 2 + 10, -mSquareSize / 2 + 10, mSquareSize / 2 - 10, mSquareSize / 2 - 10); canvas.drawArc(rectF, 270, arcAngle, false, arcPaint); //合并画布 canvas.restore(); if (!animPlaying) startAnim(); } private void startAnim() { final ValueAnimator animator = ValueAnimator.ofInt(1); animator.setDuration(1000); animator.setInterpolator(new AccelerateDecelerateInterpolator()); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { animPlaying = true; } @Override public void onAnimationEnd(Animator animator) { animPlaying = false; } @Override public void onAnimationCancel(Animator animator) { } @Override public void onAnimationRepeat(Animator animator) { } }); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float fraction = animator.getAnimatedFraction(); pointerAngle = (int) (360.0f * fraction); if (fraction <= 0.25) arcAngle = (int) (fraction * 240); else if (0.25 < fraction && fraction <= 0.75) arcAngle = (int) (-240 * fraction + 120); else arcAngle = (int) (240 * fraction - 240); Log.i("TAG", arcAngle + ":fraction:" + fraction); invalidate(); } }); animator.start(); } public int dip2px(float dpValue) { final float scale = Resources.getSystem().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mSquareSize = w; Log.i(getClass().getSimpleName(), "w:" + w + ",h:" + h); } }复制代码