一言不合先把代码贴上,具体效果,请自行粘贴后,调用start方法。我这边暂时就不做演示了,有时间添加上
public class CircleProgressView extends View { private int mSizeWidth = 200;//默认宽度 private int mSizeHeight = 200;//默认高度 private int mWidth;//控件宽 private int mHeight;//控件高 private Paint mPaint; private int radio;//主体圆半径 private boolean isDrawing = false;//是否在动画状态 private int mLinePercent; private int mCirclePercent; private int mUpPercent; private boolean isUpDone; private int mShapePercent; private int wSpace;//横向padding private int hSpace;//竖向padding private float mPaintWidth = 8f;//画笔宽度,可调 private int count = 0; public CircleProgressView(Context context) { this(context, null); } public CircleProgressView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.parseColor("#22ffffff")); mPaint.setStrokeWidth(8f); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpeMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpeMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (widthSpeMode == MeasureSpec.AT_MOST && heightSpeMode == MeasureSpec.AT_MOST) { setMeasuredDimension(mSizeWidth, mSizeHeight); } else if (widthSpeMode == MeasureSpec.AT_MOST) { setMeasuredDimension(mSizeWidth, heightSize); } else if (heightSpeMode == MeasureSpec.AT_MOST) { setMeasuredDimension(widthSize, mSizeHeight); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); wSpace = getPaddingLeft() + getPaddingRight(); hSpace = getPaddingTop() + getPaddingBottom(); mWidth = w; mHeight = h; int viewWidth = mWidth - wSpace; int viewHeight = mHeight - hSpace; radio = (int) (viewWidth > viewHeight ? (viewHeight / 2 - mPaint.getStrokeWidth()) : (viewWidth / 2 - mPaint.getStrokeWidth())); mPaintWidth = mPaintWidth > radio / 10 ? radio / 10 : mPaintWidth; Log.i("", ""); } @Override protected void onDraw(Canvas canvas) { Log.i("draw", isDrawing + "c:" + count++); super.onDraw(canvas); canvas.drawColor(Color.parseColor("#aa2a5caa")); mPaint.setStrokeWidth(mPaintWidth); RectF rectF = new RectF(getCenterLeft(), getCenterTop() , getCenterRight(), getCenterBottom()); Path path = new Path(); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.parseColor("#99eeeeee")); canvas.drawCircle(getCenterX(), getCenterY(), radio, mPaint); if (!isDrawing) { //绘制静态箭头 mPaint.setColor(Color.WHITE); canvas.drawLine(getCenterX(), getCenterY() - radio / 2, getCenterX(), getCenterY() + radio / 2, mPaint); canvas.drawCircle(getCenterX() - radio / 2, getCenterY(), getCircleRadio(), mPaint); canvas.drawCircle(getCenterX() + radio / 2, getCenterY(), getCircleRadio(), mPaint); path.moveTo(getCenterX() - radio / 2, getCenterY()); path.lineTo(getCenterX(), getCenterY() + radio / 2); path.lineTo(getCenterX() + radio / 2, getCenterY()); canvas.drawPath(path, mPaint); } else { //开始变形 mPaint.setColor(Color.WHITE); //如果小于95 就继续缩短。 95是微调值 和point大小相等 if (mLinePercent < 95) { //线段逐渐缩短(终点为mWidth/2,mHeight/2) float tmp = radio / 2 * mLinePercent / 100; canvas.drawLine(getCenterX(), getCenterY() - radio / 2 + tmp, getCenterX(), getCenterY() + radio / 2 - tmp, mPaint); mLinePercent += 5; } else { //path变成直线 if (mCirclePercent < 100) { canvas.drawCircle(getCenterX() - radio / 2, getCenterY(), getCircleRadio(), mPaint); path.moveTo(-radio / 2 + getCenterX(), getCenterY()); path.lineTo(getCenterX(), getCenterY() + radio / 2 - mCirclePercent / 100f / 2 * radio); path.lineTo(getCenterX() + radio / 2, getCenterY()); canvas.drawCircle(getCenterX() + radio / 2, getCenterY(), getCircleRadio(), mPaint); canvas.drawPath(path, mPaint); mCirclePercent += 5; //在变成直线的过程中这个点一直存在 canvas.drawCircle(getCenterX(), getCenterY(), getCircleRadio(), mPaint); } else { //绘制把点上弹的直线 //画上升的点 if (mUpPercent < 100) { //在点移动到圆弧上的时候 线是一直存在的 canvas.drawCircle(getCenterX() - radio / 2, getCenterY(), getCircleRadio(), mPaint); canvas.drawLine(getCenterX() - radio / 2, getCenterY(), getCenterX() + radio / 2, getCenterY(), mPaint); canvas.drawCircle(getCenterX() + radio / 2, getCenterY(), getCircleRadio(), mPaint); canvas.drawCircle(getCenterX(), getCenterY() - radio * mUpPercent / 100 + mPaint.getStrokeWidth(), getCircleRadio(), mPaint); mUpPercent += 5; } else//上升的点最终的位置 { canvas.drawCircle(getCenterX(), getCenterY() - radio, getCircleRadio(), mPaint); // canvas.drawPoint(getCenterX(), getCenterY() - radio, mPaint); isUpDone = true; } if (isUpDone) //改变对勾形状 if (mShapePercent < 100) { canvas.drawCircle(getCenterX() - radio / 2, getCenterY(), getCircleRadio(), mPaint); path.moveTo(getCenterX() - radio / 2, getCenterY()); path.lineTo(getCenterX(), getCenterY() + mShapePercent / 100f * radio / 2); path.lineTo(getCenterX() + radio / 2, getCenterY() - mShapePercent / 100f * radio / 2); canvas.drawCircle(getCenterX() + radio / 2, getCenterY() - mShapePercent / 100f * radio / 2, getCircleRadio(), mPaint); canvas.drawPath(path, mPaint); //动态绘制圆形百分比 if (mShapePercent < 100) { canvas.drawArc(rectF, 270, -mShapePercent / 100.0f * 360, false, mPaint); } mShapePercent += 5; } else { canvas.drawCircle(getCenterX() - radio / 2, getCenterY(), getCircleRadio(), mPaint); //绘制最终的path path.moveTo(getCenterX() - radio / 2, getCenterY()); path.lineTo(getCenterX(), getCenterY() + radio / 2); path.lineTo(getCenterX() + radio / 2, getCenterY() - radio / 2); canvas.drawCircle(getCenterX() + radio / 2, getCenterY() - radio / 2, getCircleRadio(), mPaint); canvas.drawPath(path, mPaint); // 绘制最终的圆 canvas.drawArc(rectF, 270, -360, false, mPaint); isDrawing = false; } } } if (isDrawing) postInvalidateDelayed(10); } } private int getCenterY() { return (mHeight - hSpace) / 2 + getPaddingTop(); } private int getCenterX() { return getPaddingLeft() + (mWidth - wSpace) / 2; } private int getCenterBottom() { return getCenterY() + radio; } private int getCenterRight() { return getCenterX() + radio; } private int getCenterTop() { return getCenterY() - radio; } private int getCenterLeft() { return getCenterX() - radio; } private float getCircleRadio() { return mPaint.getStrokeWidth() / 30f; } public void start() { isDrawing = true; isUpDone = false; mUpPercent = 0; mLinePercent = 0; mCirclePercent = 0; mShapePercent = 0; invalidate(); } }