/*** date:2021/1/4 0004* author:wsm (Administrator)* funcation:圆形进度条控件*/public class CircleProgressView extends View {private Paint mBackPaint, mProgPaint; // 绘制画笔private RectF mRectF; // 绘制区域private int[] mColorArray; // 圆环渐变色private int mProgress; // 圆环进度(0-100)public CircleProgressView(Context context) {this(context, null);}public CircleProgressView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);@SuppressLint("Recycle")TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularProgressView);// 初始化背景圆环画笔mBackPaint = new Paint();mBackPaint.setStyle(Paint.Style.STROKE); // 只描边,不填充mBackPaint.setStrokeCap(Paint.Cap.ROUND); // 设置圆角mBackPaint.setAntiAlias(true); // 设置抗锯齿mBackPaint.setDither(true); // 设置抖动mBackPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_backWidth, 5));mBackPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_backColor, Color.LTGRAY));// 初始化进度圆环画笔mProgPaint = new Paint();mProgPaint.setStyle(Paint.Style.STROKE); // 只描边,不填充mProgPaint.setStrokeCap(Paint.Cap.ROUND); // 设置圆角mProgPaint.setAntiAlias(true); // 设置抗锯齿mProgPaint.setDither(true); // 设置抖动mProgPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_progWidth, 10));mProgPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_progColor, Color.BLUE));// 初始化进度圆环渐变色int startColor = typedArray.getColor(R.styleable.CircularProgressView_progStartColor, -1);int firstColor = typedArray.getColor(R.styleable.CircularProgressView_progFirstColor, -1);if (startColor != -1 && firstColor != -1) mColorArray = new int[]{startColor, firstColor};else mColorArray = null;// 初始化进度mProgress = typedArray.getInteger(R.styleable.CircularProgressView_progress, 0);typedArray.recycle();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int viewWide = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();int viewHigh = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();int mRectLength = (int) ((viewWide > viewHigh ? viewHigh : viewWide) - (mBackPaint.getStrokeWidth() > mProgPaint.getStrokeWidth() ? mBackPaint.getStrokeWidth() : mProgPaint.getStrokeWidth()));int mRectL = getPaddingLeft() + (viewWide - mRectLength) / 2;int mRectT = getPaddingTop() + (viewHigh - mRectLength) / 2;mRectF = new RectF(mRectL, mRectT, mRectL + mRectLength, mRectT + mRectLength);// 设置进度圆环渐变色if (mColorArray != null && mColorArray.length > 1)mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawArc(mRectF, 0, 360, false, mBackPaint);canvas.drawArc(mRectF, 275, 360 * mProgress / 100, false, mProgPaint);}// ---------------------------------------------------------------------------------------------/*** 获取当前进度** @return 当前进度(0-100)*/public int getProgress() {return mProgress;}/*** 设置当前进度** @param progress 当前进度(0-100)*/public void setProgress(int progress) {this.mProgress = progress;invalidate();}/*** 设置当前进度,并展示进度动画。如果动画时间小于等于0,则不展示动画** @param progress 当前进度(0-100)* @param animTime 动画时间(毫秒)*/public void setProgress(int progress, long animTime) {if (animTime <= 0) setProgress(progress);else {ValueAnimator animator = ValueAnimator.ofInt(mProgress, progress);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mProgress = (int) animation.getAnimatedValue();invalidate();}});animator.setInterpolator(new OvershootInterpolator());animator.setDuration(animTime);animator.start();}}/*** 设置背景圆环宽度** @param width 背景圆环宽度*/public void setBackWidth(int width) {mBackPaint.setStrokeWidth(width);invalidate();}/*** 设置背景圆环颜色** @param color 背景圆环颜色*/public void setBackColor(@ColorRes int color) {mBackPaint.setColor(ContextCompat.getColor(getContext(), color));invalidate();}/*** 设置进度圆环宽度** @param width 进度圆环宽度*/public void setProgWidth(int width) {mProgPaint.setStrokeWidth(width);invalidate();}/*** 设置进度圆环颜色** @param color 景圆环颜色*/public void setProgColor(@ColorRes int color) {mProgPaint.setColor(ContextCompat.getColor(getContext(), color));mProgPaint.setShader(null);invalidate();}/*** 设置进度圆环颜色(支持渐变色)** @param startColor 进度圆环开始颜色* @param firstColor 进度圆环结束颜色*/public void setProgColor(@ColorRes int startColor, @ColorRes int firstColor) {mColorArray = new int[]{ContextCompat.getColor(getContext(), startColor), ContextCompat.getColor(getContext(), firstColor)};mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));invalidate();}/*** 设置进度圆环颜色(支持渐变色)** @param colorArray 渐变色集合*/public void setProgColor(@ColorRes int[] colorArray) {if (colorArray == null || colorArray.length < 2) return;mColorArray = new int[colorArray.length];for (int index = 0; index < colorArray.length; index++)mColorArray[index] = ContextCompat.getColor(getContext(), colorArray[index]);mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));invalidate();}
}
res/vasues/attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources><!-- 圆形进度条--><declare-styleable name="CircularProgressView"><attr name="backWidth" format="dimension" /> <!--背景圆环宽度--><attr name="progWidth" format="dimension" /> <!--进度圆环宽度--><attr name="backColor" format="color" /> <!--背景圆环颜色--><attr name="progColor" format="color" /> <!--进度圆环颜色--><attr name="progStartColor" format="color" /> <!--进度圆环开始颜色--><attr name="progFirstColor" format="color" /> <!--进度圆环结束颜色--><attr name="progress" format="integer" /> <!--圆环进度--></declare-styleable>
</resources>
<RelativeLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"><com.example.demo.view.CircleProgressViewandroid:layout_width="85dp"android:layout_height="85dp"app:backWidth="20dp"内边框宽度app:progColor="#20AEFF"进度条颜色app:backColor="#E6DBDBDB"默认颜色app:progWidth="20dp"进度宽度app:progress="85" />进度值<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_centerVertical="true"android:text="85%"android:textColor="#ff4d4d4d"android:textSize="13sp" /></RelativeLayout>