Android自定義圓形進度條

繪制自定義的圓形進度條,分為三個步驟,內(nèi)圓、外圓、文字。
其中內(nèi)圓和文字比較好繪制,進度條的變化是由外圓來控制的,所以核心就是繪制外圓。

首先定義分別定義這三個畫筆,兩個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);

繪制內(nèi)圓

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);

最后的效果如下圖

device-2016-10-11-180030.png

繪制完了基本的圖案,下一步就是實現(xiàn)進度條的動畫效果

進度條是實時變化的,所以需要不斷的去更新進度,進度可以用圓弧開繪制

設(shè)置進度的方法

public void setProgress(float progress) {
  if (progress > 100) {
    progress = 100;
  }
  if (progress < 0) {
    progress = 0;
  }
  mProgress = progress;
  mProgressText = "Pause";
  mStartProgress = true;
  postInvalidate();
}

在Activity中開一個線程模擬網(wǎng)絡(luò)請求后更新進度條的操作

沒30毫秒更新一次數(shù)據(jù),當(dāng)進度超過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進度轉(zhuǎn)換為圓弧的弧度,然后不斷繪制出來,這里要注意,從-90開始,也就是時鐘的0點時刻開始繪制。如果進度已經(jīng)繪制完成,或者還沒有開始,則直接繪制一個圓形。

大概思路就是這樣,最后上兩張效果圖

device-2016-10-11-175952.png
device-2016-10-11-180110.png

如果有什么更好的實現(xiàn)思路,可以一起討論學(xué)習(xí)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容