Android编程基于自定义View实现绚丽的圆形进度条功能示例

论坛 期权论坛     
niminba   2021-5-22 15:37   191   0
<p>本文实例讲述了Android编程基于自定义View实现绚丽的圆形进度条功能。分享给大家供大家参考,具体如下:</p>
<p>本文包含两个组件,首先上效果图:</p>
<p>1.ProgressBarView1(支持拖动):</p>
<p><img alt="" src="https://beijingoptbbs.oss-cn-hangzhou.aliyuncs.com/jb/2426819-44827deb0831db5df42e9f2389f0d4aa"></p>
<p>2.ProgressBarView2(不同进度值显示不同颜色,不支持拖拽):</p>
<p><img alt="" src="https://beijingoptbbs.oss-cn-hangzhou.aliyuncs.com/jb/2426819-3bb5c9a544d95df882dd6a47984004ab">&nbsp;<img alt="" src="https://beijingoptbbs.oss-cn-hangzhou.aliyuncs.com/jb/2426819-274e0bc425e810a02ae4620f9df10ba4"></p>
<p>代码不多,注释也比较详细,全部贴上了:</p>
<p>(一)ProgressBarView1:</p>
<div class="blockcode">
<pre class="brush:java;">
/**
* 自定义绚丽的ProgressBar.
*/
public class ProgressBarView1 extends View {
  /**
   * 进度条所占用的角度
   */
  private static final int ARC_FULL_DEGREE = 300;
  /**
   * 弧线的宽度
   */
  private int STROKE_WIDTH;
  /**
   * 组件的宽,高
   */
  private int width, height;
  /**
   * 进度条最大值和当前进度值
   */
  private float max, progress;
  /**
   * 是否允许拖动进度条
   */
  private boolean draggingEnabled = false;
  /**
   * 绘制弧线的矩形区域
   */
  private RectF circleRectF;
  /**
   * 绘制弧线的画笔
   */
  private Paint progressPaint;
  /**
   * 绘制文字的画笔
   */
  private Paint textPaint;
  /**
   * 绘制当前进度值的画笔
   */
  private Paint thumbPaint;
  /**
   * 圆弧的半径
   */
  private int circleRadius;
  /**
   * 圆弧圆心位置
   */
  private int centerX, centerY;
  public ProgressBarView1(Context context) {
    super(context);
    init();
  }
  public ProgressBarView1(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
  }
  public ProgressBarView1(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
  }
  private void init() {
    progressPaint = new Paint();
    progressPaint.setAntiAlias(true);
    textPaint = new Paint();
    textPaint.setColor(Color.WHITE);
    textPaint.setAntiAlias(true);
    thumbPaint = new Paint();
    thumbPaint.setAntiAlias(true);
    //使用自定义字体
    textPaint.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fangz.ttf"));
  }
  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    if (width == 0 || height == 0) {
      width = getWidth();
      height = getHeight();
      //计算圆弧半径和圆心点
      circleRadius = Math.min(width, height) / 2;
      STROKE_WIDTH = circleRadius / 12;
      circleRadius -= STROKE_WIDTH;
      centerX = width / 2;
      centerY = height / 2;
      //圆弧所在矩形区域
      circleRectF = new RectF();
      circleRectF.left = centerX - circleRadius;
      circleRectF.top = centerY - circleRadius;
      circleRectF.right = centerX + circleRadius;
      circleRectF.bottom = centerY + circleRadius;
    }
  }
  private Rect textBounds = new Rect();
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    float start = 90 + ((360 - ARC_FULL_DEGREE) &gt;&gt; 1); //进度条起始点
    float sweep1 = ARC_FULL_DEGREE * (progress / max); //进度划过的角度
    float sweep2 = ARC_FULL_DEGREE - sweep1; //剩余的角度
    //绘制起始位置小圆形
    progressPaint.setColor(Color.WHITE);
    progressPaint.setStrokeWidth(0);
    progressPaint.setStyle(Paint.Style.FILL);
    float radians = (float) (((360.0f - ARC_FULL_DEGREE) / 2) / 180 * Math.PI);
    float startX = centerX - circleRadius * (float) Math.sin(radians);
    float startY = centerY + circleRadius * (float) Math.cos(radians);
    canvas.drawCircle(startX, startY, STROKE_WIDTH / 2, progressPaint);
    //绘制进度条
    progressPaint.setStrokeWidth(STROKE_WIDTH);
    progressPaint.setStyle(Paint.Style.STROKE);//设置空心
    canvas.drawArc(circleRectF, start, sweep1, false, progressPaint);
    //绘制进度条背景
    progressPaint.setColor(Color.parseColor("#d64444"));
    canvas.drawArc(circleRectF, start + sweep1, sweep2, false, progressPaint);
    //绘制结束位置小圆形
    progressPaint.setStrokeWidth(0);
    progressPaint.setStyle(Paint.Style.FILL);
    float endX = centerX + circleRadius * (float) Math.sin(radians);
    float endY = centerY + circleRadius * (float) Math.cos(radians);
    canvas.drawCircle(endX, endY, STROKE_WIDTH / 2, progressPaint);
    //上一行文字
    textPaint.setTextSize(circleRadius &gt;&gt; 1);
    String text = (int) (100 * progress / max) + "";
    float textLen = textPaint.measureText(text);
    //计算文字高度
    textPaint.getTextBounds("8", 0, 1, textBounds);
    float h1 = textBounds.height();
    //% 前面的数字水平居中,适当调整
    float extra = text.startsWith("1") &#63; -textPaint.measureText("1") / 2 : 0;
    canvas.drawText(text, centerX - textLen / 2 + extra, centerY - 30 + h1 / 2, textPaint);
    //百分号
    textPaint.setTextSize(circleRadius &gt;&gt; 2);
    canvas.drawText("%", centerX + textLen / 2 + extra + 5, centerY - 30 + h1 / 2, textPaint);
    //下
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP