Android 實現自訂圓形進度條:
Android 自訂view,在大多數項目中根據客戶需求及使用者的體驗度來說,都要重新寫控制項的來展示漂亮的介面,這裡就對圓形進度條說下如何?。
繪製自訂的圓形進度條,分為三個步驟,內圓、外圓、文字。
其中內圓和文字比較好繪製,進度條的變化是由外圓來控制的,所以核心就是繪製外圓。
首先定義分別定義這三個畫筆,兩個Paint和一個TextPaint
mCirclePaint = new Paint();mCirclePaint.setAntiAlias(true);mCirclePaint.setStrokeWidth(CIRCLE_LINE_WIDTH);mCirclePaint.setStyle(Paint.Style.STROKE);mCirclePaint.setColor(ContextCompat.getColor(context, R.color.circle_color));mCircleInnerPaint = new Paint();mCircleInnerPaint.setAntiAlias(true);mCircleInnerPaint.setStyle(Paint.Style.FILL);mCircleInnerPaint.setColor(ContextCompat.getColor(context, R.color.circle_inner_color));mTextPaint = new TextPaint();mTextPaint.setAntiAlias(true);mTextPaint.setStyle(Paint.Style.FILL);mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);mTextPaint.setColor(ContextCompat.getColor(context, R.color.circle_text_color));mTextPaint.setTextSize(TEXT_SIZE);
然後讓我們分別繪製出這三個部分擷取自訂View的寬和高
float halfWidth = getMeasuredWidth() / 2;
float halfHeight = getMeasuredHeight() / 2;
繪製外圓
canvas.drawCircle(halfWidth, halfHeight, CIRCLE_RADIUS,mCirclePaint);
繪製內圓
canvas.drawCircle(halfWidth, halfHeight,CIRCLE_RADIUS - CIRCLE_LINE_WIDTH / 2,mCircleInnerPaint);
繪製文字
canvas.drawText(mProgressText,halfWidth - mTextPaint.measureText(mProgressText) / 2,halfHeight - (mTextPaint.ascent() + mTextPaint.descent()) / 2,mTextPaint);
最後的效果如下圖
繪製完了基本的圖案,下一步就是實現進度條的動畫效果
進度條是即時變化的,所以需要不斷的去更新進度,進度可以用圓弧開繪製
設定進度的方法
public void setProgress(float progress) { if (progress > 100) { progress = 100; } if (progress < 0) { progress = 0; } mProgress = progress; mProgressText = "Pause"; mStartProgress = true; postInvalidate();}
在Activity中開一個線程類比網路請求後更新進度條的操作
沒30毫秒更新一次資料,當進度超過100,停止重新整理介面
private void startProgress() { new Thread() { @Override public void run() { super.run(); float currentProgress = mCustomView.getCurrentProgress(); ++currentProgress; mCustomView.setProgress(currentProgress); try { sleep(30); if (currentProgress <= 100) { startProgress(); } else { mCustomView.progressFinished(); } } catch (InterruptedException e) { e.printStackTrace(); } } }.start();}
最核心的部分,進度更新後更新繪製圓形進度條
float halfWidth = getMeasuredWidth() / 2;float halfHeight = getMeasuredHeight() / 2;if (null == mCircleRectF) { mCircleRectF = new RectF(halfWidth - CIRCLE_RADIUS, halfHeight - CIRCLE_RADIUS, halfWidth + CIRCLE_RADIUS, halfHeight + CIRCLE_RADIUS);}if (mStartProgress) { float swipeProgress = mProgress / 100f * 360; LogUtils.e("swipeProgress = " + swipeProgress); canvas.drawArc(mCircleRectF, -90, swipeProgress, true, mCirclePaint);} else { canvas.drawCircle(halfWidth, halfHeight, CIRCLE_RADIUS,mCirclePaint);}
繪製的思路就是把progress進度轉換為圓弧的弧度,然後不斷繪製出來,這裡要注意,從-90開始,也就是時鐘的0點時刻開始繪製。如果進度已經繪製完成,或者還沒有開始,則直接繪製一個圓形。
大概思路就是這樣,最後上兩張效果圖
如果有什麼更好的實現思路,可以一起討論學習。
感謝閱讀,希望能協助到大家,謝謝大家對本站的支援!