Share a circular progress bar for your reference, project address
https://download.csdn.net/download/weixin_40998254/10595267
The effect is as follows
The following is the code of the custom progress bar. It is a simple version at present, but the comments are very detailed and easy to expand.
The first is the code of custom View
/** * Author: gjp on July 26, 2018 15:12 * Email: xiaoxiao9575@126.com * Description: */ public class CircularProgressView extends View { private Context mContext; private Paint mPaint; private int mProgress = 0; private static int MAX_PROGRESS = 100; /** * radian */ private int mAngle; /** * Middle text */ private String mText; /** * Cylindrical color */ private int outRoundColor; /** * Color of inner circle */ private int inRoundColor; /** * Line width */ private int roundWidth; private int style; /*** Font color*/ private int textColor; /** * font size */ private float textSize; /** * Whether the font is bold */ private boolean isBold; /** * Progress bar color */ private int progressBarColor; public CircularProgressView(Context context) { this(context, null); } public CircularProgressView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircularProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; init(attrs); } @TargetApi(21) public CircularProgressView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mContext = context; init(attrs); } /** * Resolve custom properties * @param attrs */ public void init(AttributeSet attrs) { mPaint = new Paint(); TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar); outRoundColor = typedArray.getColor(R.styleable.CircleProgressBar_outCircleColor, getResources().getColor(R.color.colorPrimary)); inRoundColor = typedArray.getColor(R.styleable.CircleProgressBar_inCircleColor, getResources().getColor(R.color.colorPrimaryDark)); progressBarColor = typedArray.getColor(R.styleable.CircleProgressBar_progressColor, getResources().getColor(R.color.colorAccent)); isBold = typedArray.getBoolean(R.styleable.CircleProgressBar_textBold, false); textColor = typedArray.getColor(R.styleable.CircleProgressBar_textColor, Color.BLACK); roundWidth = typedArray.getDimensionPixelOffset(R.styleable.CircleProgressBar_lineWidth, 20); typedArray.recycle(); } @Override protected void onDraw(Canvas canvas) { /** * Extra circle */ super.onDraw(canvas); int center = getWidth() / 2;//Center of a circle int radius = (center - roundWidth / 2);// radius mPaint.setColor(outRoundColor); //Cylindrical color mPaint.setStrokeWidth(roundWidth); //Line width mPaint.setStyle(Paint.Style.STROKE); //Hollow circle mPaint.setAntiAlias(true); //Eliminating sawtooth canvas.drawCircle(center, center, radius, mPaint); //Inner circle mPaint.setColor(inRoundColor); radius = radius - roundWidth; canvas.drawCircle(center, center, radius, mPaint); //Drawing progress is an arc mPaint.setColor(progressBarColor); RectF rectF = new RectF(center - radius, center - radius, center + radius, center + radius);//Circumscribed rectangle of arc range canvas.drawArc(rectF, -90, mAngle, false, mPaint); canvas.save(); //Save previously drawn before panning the canvas // Drawing the ball at the end of the progress and rotating the canvas mPaint.setStyle(Paint.Style.FILL); // Move canvas coordinate origin to center canvas.translate(center, center); // Rotation is the same as progress, because progress starts at - 90 degrees, so - 90 degrees canvas.rotate(mAngle - 90); // Similarly, starting from the center of the circle, directly translate the origin to the position where you want to draw the ball canvas.translate(radius, 0); canvas.drawCircle(0, 0, roundWidth, mPaint); // Restore canvas coordinates after drawing canvas.restore(); // Draw text to translate coordinates to center canvas.translate(center, center); mPaint.setStrokeWidth(0); mPaint.setColor(textColor); if (isBold) { //Bold font mPaint.setTypeface(Typeface.DEFAULT_BOLD); } if (!TextUtils.isEmpty(mText)) { // Dynamically set the text length as circle radius and calculate the font size float textLength = mText.length(); textSize = radius / textLength; mPaint.setTextSize(textSize); // Draw text in the middle float textWidth = mPaint.measureText(mText); canvas.drawText(mText, -textWidth / 2, textSize / 2, mPaint); } } public int getProgress() { return mProgress; } /** * Setting progress * @return */ public void setProgress(int p) { if (p > MAX_PROGRESS) { mProgress = MAX_PROGRESS; mAngle = 360; } else { mProgress = p; mAngle = 360 * p / MAX_PROGRESS; } //Update canvas invalidate(); } public String getText() { return mText; } /** * Set text * @param mText */ public void setText(String mText) { this.mText = mText; invalidate(); } }
styles.xml needs to be added
<declare-styleable name="CircleProgressBar"> <attr name="outCircleColor" format="color"></attr> <attr name="inCircleColor" format="color"></attr> <attr name="progressColor" format="color"></attr> <attr name="textColor" format="color"></attr> <attr name="textBold" format="boolean"></attr> <attr name="lineWidth" format="dimension"></attr> </declare-styleable>
Example code referenced in the layout file
<com.xiaoxiao9575.circularprogressapplication.CircularProgressView android:id="@+id/progress_bar" android:layout_centerInParent="true" android:layout_centerHorizontal="true" android:layout_width="150dp" android:layout_height="150dp" app:inCircleColor="#DCDCDC" app:outCircleColor="#F0F0F0" app:progressColor="#50CE7B" app:textBold="true" app:textColor="#50CE7B" app:lineWidth="5dp" />
Specific control progress in Activity
public class MainActivity extends AppCompatActivity { private CircularProgressView progress_bar; @SuppressLint("HandlerLeak") private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); progress_bar.setProgress(msg.what); progress_bar.setText(progress_bar.getProgress()+"%"); addProgress(msg.what); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { progress_bar = (CircularProgressView) findViewById(R.id.progress_bar); progress_bar.setProgress(0); progress_bar.setText(progress_bar.getProgress()+"%"); addProgress(0); } private void addProgress(int i) { if (i>=100){ i = 0; }else { ++i; } handler.sendEmptyMessageDelayed(i, 100); } }
There's nothing to say about the customized circular progress bar. The code annotation is very detailed, and the usage methods are pasted out. Because it's easy to expand, it's pasted out for reference and for your own record. If there's time, a more perfect circular progress bar will be sent to GitHub later.