一个最基础的自定义View 圆形进度条,可设置背景色、进度条颜色(渐变色)下载进度控制;可二次定制度高;
核心代码:
@Overrideprotected void onDraw(@NonNull Canvas canvas) {super.onDraw(canvas);int mW = getMeasuredWidth();int mH = getMeasuredHeight();int centerX = mW/2;int centerY = mH/2;Log.i(TAG, "onDraw: "+mW +"-" +mH);//画背景色canvas.save();paintBg.setColor(backgroundColor);RectF rectBg = new RectF(strokeWidth,strokeWidth,mW-strokeWidth,mH-strokeWidth);canvas.drawArc(rectBg,0,360,false , paintBg);//画进度条颜色float ratio = (float) Math.min(progress / max , 1.00);paint.setColor(loadingColor); //设置进度条颜色
// SweepGradient sweepGradient = new SweepGradient(centerX , centerY , new int[]{loadingColor , Color.YELLOW} , null);
// paint.setShader(sweepGradient); //设置进度条渐变色paint.setStrokeCap(Paint.Cap.ROUND); 设置画笔边缘为半圆状canvas.drawArc(rectBg,0,360*ratio,false , paint);canvas.restore();//画中间的文案paintText.setTextSize(dp2px(18));paintText.setColor(Color.BLACK);paintText.setTextAlign(Paint.Align.CENTER);Paint.FontMetrics fontMetrics = paintText.getFontMetrics();float disY = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;canvas.drawText(progress+"%" , centerX , centerY+disY , paintText);}
全部代码:
package com.cuichen.mytestdemo.view;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;import com.cuichen.mytestdemo.R;public class CircleProgressView extends View {private final String TAG = CircleProgressView.class.getSimpleName();public CircleProgressView(Context context) {super(context);}public CircleProgressView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);initAttrs(attrs);}public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initAttrs(attrs);}public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);initAttrs(attrs);}private void initAttrs( @Nullable AttributeSet attrs){TypedArray typedArray = getContext().obtainStyledAttributes(attrs , R.styleable.CircleProgress);try{backgroundColor = typedArray.getColor(R.styleable.CircleProgress_backgroundColorCircle , Color.parseColor("#5503DAC5"));loadingColor = typedArray.getColor(R.styleable.CircleProgress_progressColorCircle ,Color.parseColor("#FF018786"));strokeWidth = (int) typedArray.getDimension(R.styleable.CircleProgress_strokeWidthCircle , 18);max = typedArray.getInt(R.styleable.CircleProgress_maxCircle , 100);progress = typedArray.getInt(R.styleable.CircleProgress_progressCircle , 50);}catch (Exception e){typedArray.recycle();}}private int strokeWidth = 18;private float progress = 0f;private float max = 100f;private int backgroundColor;private int loadingColor;final int DEFAULT_HEIGHT_DP = 66;Paint paintBg , paint , paintText;void init(){paintBg = new Paint();paintBg.setAntiAlias(true);paintBg.setStyle(Paint.Style.STROKE);paintBg.setStrokeWidth(strokeWidth);paint = new Paint();paint.setAntiAlias(true);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(strokeWidth);paintText = new Paint();paintText.setAntiAlias(true);}public void setProgress(int progress){this.progress = progress;invalidate();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);Log.i(TAG, "onMeasure: ");int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);int height = 0;switch (heightSpecMode){case MeasureSpec.AT_MOST:height = dp2px(DEFAULT_HEIGHT_DP);break;case MeasureSpec.EXACTLY:case MeasureSpec.UNSPECIFIED:height = heightSpecSize;break;}setMeasuredDimension(widthSpecSize, height);if(paint == null) {init();}}//RectF//left:左边坐标;在绘制中常表示为起点的Y轴坐标//top:上边左边;在绘制中常表示为起点的X轴坐标//right:右边坐标;在绘制中常表示为终点的X轴坐标//bottom:下边坐标;在绘制中常表示为终点的Y轴坐标@Overrideprotected void onDraw(@NonNull Canvas canvas) {super.onDraw(canvas);int mW = getMeasuredWidth();int mH = getMeasuredHeight();int centerX = mW/2;int centerY = mH/2;Log.i(TAG, "onDraw: "+mW +"-" +mH);//画背景色canvas.save();paintBg.setColor(backgroundColor);RectF rectBg = new RectF(strokeWidth,strokeWidth,mW-strokeWidth,mH-strokeWidth);canvas.drawArc(rectBg,0,360,false , paintBg);//画进度条颜色float ratio = (float) Math.min(progress / max , 1.00);paint.setColor(loadingColor); //设置进度条颜色
// SweepGradient sweepGradient = new SweepGradient(centerX , centerY , new int[]{loadingColor , Color.YELLOW} , null);
// paint.setShader(sweepGradient); //设置进度条渐变色paint.setStrokeCap(Paint.Cap.ROUND); 设置画笔边缘为半圆状canvas.drawArc(rectBg,0,360*ratio,false , paint);canvas.restore();//画中间的文案paintText.setTextSize(dp2px(18));paintText.setColor(Color.BLACK);paintText.setTextAlign(Paint.Align.CENTER);Paint.FontMetrics fontMetrics = paintText.getFontMetrics();float disY = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;canvas.drawText(progress+"%" , centerX , centerY+disY , paintText);}private int dp2px(int dp){float density = getContext().getResources().getDisplayMetrics().density;return (int) (dp * density);}
}
<declare-styleable name="CircleProgress"><attr name="backgroundColorCircle" format="color"/><attr name="progressColorCircle" format="color"/><attr name="strokeWidthCircle" format="dimension"/><attr name="maxCircle" format="integer"/><attr name="progressCircle" format="integer"/></declare-styleable>