素材巴巴 > 程序开发 >

Android 绘制百分比圆环进度条

程序开发 2023-09-16 11:17:47

在学习自定义Vew的时候,看到一篇文章,http://blog.csdn.net/nugongahou110/article/details/49159189,然后顺着其思路写了一下,实现效果如下:

这里写图片描述

我们要做的事情:实现一个百分比的圆环进度条,包含三部分,分别是:

  1. 百分比文字
  2. 背景圆
  3. 动态圆环

我们要做的思路:

  1. 先分别绘制对应的图形;
  2. 使图形能动态变化;
  3. 文字显示百分比与圆环进度对应;

会涉及到的基本知识点:

  1. 自定义View 会重写三个方法;
  2. onMeasure()方法中,测量规则、测量大小、测量模式;
  3. TypedArray 获取自定义属性;
  4. canvas 绘制矩形内切圆;

自定义View PercentCircle.java:

public class PercentCircle extends View{/*** 绘制百分比的圆,一共有三部分,分别是里面的文字、背景圆、圆环;* 思路:首先需要三支画笔, 设置画笔对应的属性等;*/private Paint mTextPaint;private Paint mBackgroundPaint;private Paint mRingPaint;private int mCircleX;private int mCircleY;private float mCurrentAngle;private RectF mArcRectF;private float mStartSweepValue;private float mTargetPercent;private float mCurrentPercent;private int mDefaultRadius = 60;private int mRadius;private int mDefaultBackgroundColor = 0xffafb4db;private int mBackgroundColor;private int mDefaultRingColor = 0xff6950a1;private int mRingColor;private int mDefaultTextSize;private int mTextSize;private int mDefaultTextColor = 0xffffffff;private int mTextColor;public PercentCircle(Context context) {super(context);init(context);}public PercentCircle(Context context, AttributeSet attrs) {super(context, attrs);// 自定义属性,attrs// 使用TypedArrayTypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PercentCircle);// 背景圆的半径mRadius = typedArray.getInt(R.styleable.PercentCircle_radius, mDefaultRadius);// 背景圆的颜色mBackgroundColor = typedArray.getColor(R.styleable.PercentCircle_background_color, mDefaultBackgroundColor);// 文字的颜色 默认白色mTextColor = typedArray.getColor(R.styleable.PercentCircle_text_color, mDefaultTextColor);// 外圆环的颜色mRingColor = typedArray.getColor(R.styleable.PercentCircle_ring_color, mDefaultRingColor);// Be sure to call recycle() when done with themtypedArray.recycle();init(context);}public PercentCircle(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}private void init(Context context){//圆环开始角度 -90° 正北方向mStartSweepValue = -90;//当前角度mCurrentAngle = 0;//当前百分比mCurrentPercent = 0;//设置中心园的画笔mBackgroundPaint = new Paint();mBackgroundPaint.setAntiAlias(true);mBackgroundPaint.setColor(mBackgroundColor);mBackgroundPaint.setStyle(Paint.Style.FILL);//设置文字的画笔mTextPaint = new Paint();mTextPaint.setColor(mTextColor);mTextPaint.setAntiAlias(true);mTextPaint.setStyle(Paint.Style.FILL);mTextPaint.setStrokeWidth((float) (0.025*mRadius));mTextPaint.setTextSize(mRadius/2);   //文字大小为半径的一半mTextPaint.setTextAlign(Paint.Align.CENTER);//设置外圆环的画笔mRingPaint = new Paint();mRingPaint.setAntiAlias(true);mRingPaint.setColor(mRingColor);mRingPaint.setStyle(Paint.Style.STROKE);mRingPaint.setStrokeWidth((float) (0.075*mRadius));//获得文字的字号 因为要设置文字在圆的中心位置mTextSize = (int) mTextPaint.getTextSize();}// 主要是测量wrap_content时候的宽和高,因为宽高一样,只需要测量一次宽即可,高等于宽@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(measure(widthMeasureSpec), measure(widthMeasureSpec));}// 当wrap_content的时候,view的大小根据半径大小改变,但最大不会超过屏幕private int measure(int measureSpec){int result = 0;//1、先获取测量模式 和 测量大小//2、如果测量模式是MatchParent 或者精确值,则宽为测量的宽//3、如果测量模式是WrapContent ,则宽为 直径值 与 测量宽中的较小值;否则当直径大于测量宽时,会绘制到屏幕之外;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);if( specMode == MeasureSpec.EXACTLY){result = specSize;}else {//result = 2*mRadius;//result =(int) (1.075*mRadius*2);result =(int) (mRadius*2 + mRingPaint.getStrokeWidth()*2);if(specMode == MeasureSpec.AT_MOST){result = Math.min(result, specSize);}}return result;}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);//1、如果半径大于圆心的横坐标,需要手动缩小半径的值,否则画到屏幕之外;//2、改变了半径,则需要重新设置字体大小;//3、改变了半径,则需要重新设置外圆环的宽度//4、画背景圆的外接矩形,用来画圆环;mCircleX = getMeasuredWidth()/2;mCircleY = getMeasuredHeight()/2;if(mRadius > mCircleX){mRadius = mCircleX;mRadius = (int) (mCircleX-0.075*mRadius);mTextPaint.setStrokeWidth((float) (0.025*mRadius));mTextPaint.setTextSize(mRadius/2);mRingPaint.setStrokeWidth((float) (0.075*mRadius));mTextSize = (int) mTextPaint.getTextSize();}mArcRectF = new RectF(mCircleX-mRadius, mCircleY-mRadius, mCircleX+mRadius, mCircleY+mRadius);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//1、画中间背景圆//2、画文字//3、画圆环//4、判断进度,重新绘制canvas.drawCircle(mCircleX, mCircleY, mRadius, mBackgroundPaint);canvas.drawText(String.valueOf(mCurrentPercent)+"%", mCircleX, mCircleY+mTextSize/4, mTextPaint);canvas.drawArc(mArcRectF, mStartSweepValue, mCurrentAngle, false, mRingPaint);if(mCurrentPercent < mTargetPercent){//当前百分比+1mCurrentPercent+=1;//当前角度+360mCurrentAngle+=3.6;//每10ms重画一次postInvalidateDelayed(10);}//canvas.drawRect(mArcRectF, mRingPaint);}public void setTargetPercent(float targetPercent){mTargetPercent = targetPercent;}
 }

标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。