Sometimes when we are programming, we need to use canvas to customize drawing graphics. Here we introduce the method of drawing circles, rings and arcs.
1. Drawing a circle and drawing a circle can be accomplished by calling drawCircle. The API method is as follows:
Canvas.drawCircle(float cx, float cy, float radius, Paint paint); //cx, CY are coordinates of the center of a circle, radius is the radius of a circle, paint is the brush. A little more about radius is explained here. The radius length is half the width of the center of the circle to the stoken circle, that is, radius = center -circleWidth/2.
When we want to draw a circle, we can draw the circle effect by setting the style of paint brush to hollow.
paint.setStyle(Paint.Style.STROKE); //Hollow
2. The API method of drawing arcs is as follows:
Canvas.drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint);
The oval parameter represents the rectangular area needed to draw this arc. Its construction method is as follows: RectF(float left, float top, float right, float bottom). It is also important to note that the left, top, right and bottom here represent the coordinates of the center point of the stoken of the arc border. Here I think of the arc as a standard circle of 360 degrees. However, it may only be one of the arcs, as shown in the figure:
startAngle represents the angular position of the beginning of the arc and defaults to 0 at 3 o'clock.
SwepAngle represents the angle size to be drawn
useCenter means whether the central area needs to be filled. true means filling. After filling, it will not be a fan-shaped shape, but a circle cut by a line segment; false means only drawing an arc line.
Paints represent brushes
3. Using the method of drawing circles and arcs, we can make an effect similar to the circular progressbar by ourselves, as follows:
Above is a continuous drawing dynamic effect, which takes a circle as a low map, and then draws an arc on the circle; below is a filling effect arc.
Customize a View first, and the custom attributes are not given:
public class CustomProgressBar extends View {
private int firstColor;
private int secondColor;
private int circleWidth;
private Paint paint;
private int progress;
public CustomProgressBar(Context context) {
this(context,null);
}
public CustomProgressBar(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public CustomProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomProgressBar, defStyleAttr, 0);
int n = a.getIndexCount();
for(int i=0;i<n;i++){
int attr = a.getIndex(i);
switch(attr){
case R.styleable.CustomProgressBar_firstColor:
firstColor = a.getColor(attr, Color.GREEN);
break;
case R.styleable.CustomProgressBar_secondColor:
secondColor = a.getColor(attr, Color.BLUE);
break;
case R.styleable.CustomProgressBar_circleWidth:
circleWidth = a.getDimensionPixelSize(attr, 20);
break;
}
}
a.recycle();
paint = new Paint();
}
public void setProgress(int pro){
if(progress!=0 &&pro ==0){
//Color substitution
int tempcolor = firstColor;
firstColor = secondColor;
secondColor = tempcolor;
}
this.progress = pro;
invalidate();
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int center = getWidth()/2;
int radius = center -circleWidth/2; //Set the radius of the circle
paint.setStrokeWidth(circleWidth); //Set the width of the ring
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE); //Hollow
RectF oval = new RectF(circleWidth/2 , circleWidth/2, getWidth()-circleWidth/2, getHeight()-circleWidth/2);
paint.setColor(firstColor);
canvas.drawCircle(center, center, radius, paint); //donut
paint.setColor(secondColor);
canvas.drawArc(oval, -90, progress, false, paint); //draw arc
}
Then start a thread in Activity, constantly set the progress of the arc, and then redraw:
Handler handler = new Handler(){
public void dispatchMessage(android.os.Message msg) {
switch(msg.what){
case 0x1:
customview.setProgress(progress);
break;
}
};
};
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
thread.sleep(50); //Drawing once every 50ms
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.sendEmptyMessage(0x1);
progress++;
if(progress>360){
progress = 0;
}
}
}
});