Android自定义圆形进度条

LynetteBost 8年前
   <p>绘制自定义的圆形进度条,分为三个步骤,内圆、外圆、文字。</p>    <p>其中内圆和文字比较好绘制,进度条的变化是由外圆来控制的,所以核心就是绘制外圆。</p>    <h2><strong>首先定义分别定义这三个画笔,两个Paint和一个TextPaint</strong></h2>    <pre>  <code class="language-java">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);</code></pre>    <h2><strong>然后让我们分别绘制出这三个部分</strong></h2>    <h3><strong>获取自定义View的宽和高</strong></h3>    <pre>  <code class="language-java">float halfWidth = getMeasuredWidth() / 2;  float halfHeight = getMeasuredHeight() / 2;</code></pre>    <h3><strong>绘制外圆</strong></h3>    <pre>  <code class="language-java">canvas.drawCircle(halfWidth, halfHeight, CIRCLE_RADIUS,mCirclePaint);</code></pre>    <h3><strong>绘制内圆</strong></h3>    <pre>  <code class="language-java">canvas.drawCircle(halfWidth, halfHeight,CIRCLE_RADIUS - CIRCLE_LINE_WIDTH / 2,mCircleInnerPaint);</code></pre>    <h3><strong>绘制文字</strong></h3>    <pre>  <code class="language-java">canvas.drawText(mProgressText,halfWidth - mTextPaint.measureText(mProgressText) / 2,halfHeight - (mTextPaint.ascent() + mTextPaint.descent()) / 2,mTextPaint);</code></pre>    <p>最后的效果如下图</p>    <p><img src="https://simg.open-open.com/show/24860487dec0d5c2afc58282313eb58d.png"></p>    <p style="text-align:center">device-2016-10-11-180030.png</p>    <h2><strong>绘制完了基本的图案,下一步就是实现进度条的动画效果</strong></h2>    <p>进度条是实时变化的,所以需要不断的去更新进度,进度可以用圆弧开绘制</p>    <h3><strong>设置进度的方法</strong></h3>    <pre>  <code class="language-java">public void setProgress(float progress) {    if (progress > 100) {      progress = 100;    }    if (progress < 0) {      progress = 0;    }    mProgress = progress;    mProgressText = "Pause";    mStartProgress = true;    postInvalidate();  }</code></pre>    <h3><strong>在Activity中开一个线程模拟网络请求后更新进度条的操作</strong></h3>    <p>没30毫秒更新一次数据,当进度超过100,停止刷新界面</p>    <pre>  <code class="language-java">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();  }</code></pre>    <h3><strong>最核心的部分,进度更新后更新绘制圆形进度条</strong></h3>    <pre>  <code class="language-java">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);  }</code></pre>    <p>绘制的思路就是把progress进度转换为圆弧的弧度,然后不断绘制出来,这里要注意,从-90开始,也就是时钟的0点时刻开始绘制。如果进度已经绘制完成,或者还没有开始,则直接绘制一个圆形。</p>    <p>大概思路就是这样,最后上两张效果图</p>    <p><img src="https://simg.open-open.com/show/bd12b85fe2b4ba8b4ff227cbdc072cc6.png"></p>    <p>device-2016-10-11-175952.png</p>    <p><img src="https://simg.open-open.com/show/211fd13d54c032bd0c00578d9d706d1c.png"></p>    <p style="text-align:center">device-2016-10-11-180110.png</p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/fd5616685d3d</p>    <p> </p>