Effect chart
First, draw the ring
The first one to draw is the ring
1: Ring Drawing function
Ring API
public void DrawArc (RECTF oval, float startangle, float sweepangle, Boolean usecenter, Paint Paint)
Parameter description
Oval: The Ellipse object where the arc is located.
StartAngle: The starting angle of the arc.
Sweepangle: The angle of the arc.
Usecenter: Whether the RADIUS line is displayed, true indicates that the radius line between the arc and the center is displayed, and False indicates that it is not displayed.
Paint: The brush that is used when drawing.
Circlecenter radius of radius ring of entire circle radius
RECTF oval = new RECTF (Circlecenter-radius, Circlecenter-radius, Circlecenter + R Adius, Circlecenter + radius);
Because -90° is starting 12 o'clock, so starting at 90 progress for Progress
Canvas.drawarc (Oval, -90, (float) (Progress * 3.6), false, paint);
2: to the ring color
Because the gradient effect API is also available
The name of the function is: sweepgradient
Constructors
Public sweepgradient (float CX, float CY, int[] colors, float[] positions)
CX Render center point x coordinates
Cy Render Center Y-point coordinates
Colors the array of colors to be rendered around the center, at least two color values
Positions an array of colors relative to the position, nullable, NULL, and evenly distributed along the gradient line
Public sweepgradient (float CX, float CY, int color0, int color1)
CX Render center point x coordinates
Cy Render Center point y-coordinate
Color0 Start Rendering Color
Color1 End Rendering Color
Implementing Styles
Gradient colors You can add many kinds but at least stay in 2 colors above
int[] colors = {0xffff4639, 0xffcdd513, 0xff3cdf5f};
Circlewidth the diameter of the circle takes center point
sweepgradient sweepgradient = new Sweepgradient (THIS.CIRCLEWIDTH/2, THIS.CIRCLEWIDTH/2, CO lors, null);
But the final effect is that the gradient start angle starts at 0 °, but we want to start with -90°, so we need to rotate the drawn circle.
Rotate it or it starts at 0 degrees
. Matrix matrix = new Matrix ();
Matrix.setrotate ( -90, THIS.CIRCLEWIDTH/2, THIS.CIRCLEWIDTH/2);
Sweepgradient.setlocalmatrix (matrix);
Finally add a gradient to the ring
Paint.setshader (sweepgradient);
Because it is necessary to maintain the adoption of the first ring gradient, so in the drawing time after the use of the set
3: Draw the rest of the progress
The same is the start angle of the drawing circle
Similarly, because it is inverted, it can be drawn to the -90°
Canvas.drawarc (Oval, -90, (float) (-(100-progress) * 3.6), false, paint according to the current colored angle end angle. ;
The final implementation effect is shown in Figure 1
Second, the scale
1: Ring Scale
is to divide the whole circle according to the scale size, calculate each angle and then according to the current progress calculation of the display of several rings and then draw up, the scale used is also a ring, but the angle is very small
As follows
float start = -90f;
float p = ((float) maxcolornumber/(float);
p = (int) (progress * p);
for (int i = 0; i < p i++) {
paint.setcolor (roundbackgroundcolor);
Draw the interval quickly
Canvas.drawarc (Oval, start + Singlpoint-linewidth, LineWidth, False, paint);
Start = (start + singlpoint);
}
2: Text scale
That is, the drawing of text is the corresponding rotation after the text is drawn
Draw a text scale
for (int i = 1; I <= i++) {
canvas.save ();//Save the current canvas
canvas.rotate (360/10 * I, Circlecenter, Circlecenter);
Canvas.drawtext (i * + "", Circlecenter, Circlecenter-radius + ROUNDWIDTH/2 + getdpvalue (4) + TEXTSIZE, mPaintText);
Canvas.restore ();//
}
Finally, the entire view code
Package com.example.shall.myapplication;
Import Android.content.Context;
Import Android.content.res.TypedArray;
Import Android.graphics.Canvas;
Import Android.graphics.Matrix;
Import Android.graphics.Paint;
Import Android.graphics.RectF;
Import android.graphics.SweepGradient;
Import Android.util.AttributeSet;
Import Android.util.TypedValue;
Import Android.view.View;
public class Circularringpercentageview extends View {private Paint Paint;
private int circlewidth;
private int roundbackgroundcolor;
private int textcolor;
private float textsize;
private float roundwidth;
Private float progress = 0;
Private int[] Colors = {0xffff4639, 0xffcdd513, 0xff3cdf5f};
private int radius;
Private RECTF Oval;
Private Paint Mpainttext;
private int maxcolornumber = 100;
Private float singlpoint = 9;
private float linewidth = 0.3f;
private int circlecenter;
Private Sweepgradient sweepgradient;
Private Boolean isline; /** * Number of Split * * @param maxcolornumber quantity * * public void SEtmaxcolornumber (int maxcolornumber) {this.maxcolornumber = Maxcolornumber;
Singlpoint = (float) 360/(float) maxcolornumber;
Invalidate ();
/** * is the line * * @param lines true is false * */public void Setline (Boolean line) {isline = linear;
Invalidate ();
public int getcirclewidth () {return circlewidth;
The public Circularringpercentageview {This (context, NULL);
Public Circularringpercentageview (context, AttributeSet attrs) {This (context, attrs, 0); Circularringpercentageview (context, AttributeSet attrs, int defstyle) {Super (context, Attrs, Defstyle
);
TypedArray Mtypedarray = context.obtainstyledattributes (Attrs, r.styleable.circularring);
Maxcolornumber = Mtypedarray.getint (R.styleable.circularring_circlenumber, 40);
Circlewidth = Mtypedarray.getdimensionpixeloffset (R.styleable.circularring_circlewidth, GetDpValue (180)); Roundbackgroundcolor = Mtypedarray.getcolor (R.STYLEABLE.CIRCULARRING_ROUNDCOlor, 0XFFDDDDDD);
TextColor = Mtypedarray.getcolor (R.styleable.circularring_circletextcolor, 0xff999999);
Roundwidth = Mtypedarray.getdimension (R.styleable.circularring_circleroundwidth, 40);
Textsize = Mtypedarray.getdimension (R.styleable.circularring_circletextsize, Getdpvalue (8));
Colors[0] = Mtypedarray.getcolor (R.styleable.circularring_circlecolor1, 0xffff4639);
COLORS[1] = Mtypedarray.getcolor (R.styleable.circularring_circlecolor2, 0xffcdd513);
COLORS[2] = Mtypedarray.getcolor (R.styleable.circularring_circlecolor3, 0xff3cdf5f);
Initview ();
Mtypedarray.recycle (); /** * blank out color background * * @param roundbackgroundcolor */public void Setroundbackgroundcolor (int roundbackgroundcolor)
{this.roundbackgroundcolor = Roundbackgroundcolor;
Paint.setcolor (Roundbackgroundcolor);
Invalidate ();
/** * Dial Font Color * * @param textcolor * * public void SetTextColor (int textcolor) {this.textcolor = TextColor;
Mpainttext.setcolor (TextColor);
Invalidate (); }
/** * Scale Font Size * * @param textsize */public void settextsize (float textsize) {this.textsize = Textsize;
Mpainttext.settextsize (TEXTSIZE);
Invalidate (); /** * Gradient Color * * @param colors */public void setcolors (int[] colors) {if (Colors.length < 2) {throw n
EW illegalargumentexception ("Colors length < 2");
} this.colors = colors;
Sweepgradientinit ();
Invalidate ();
/** * Interval Angle Size * * @param linewidth/public void Setlinewidth (float linewidth) {this.linewidth = linewidth;
Invalidate (); private int Getdpvalue (int w) {return (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, W, GetContext (). g
Etresources (). Getdisplaymetrics ()); /** * Ring Width * * @param roundwidth width/public void setroundwidth (float roundwidth) {this.roundwidth = Round
Width;
if (Roundwidth > Circlecenter) {this.roundwidth = Circlecenter; RADIUS = (int) (CIRCLECENTER-THIS.ROUNDWIDTH/2); Radius of the ring Oval.left = CircLecenter-radius;
Oval.right = circlecenter + radius;
Oval.bottom = circlecenter + radius;
Oval.top = Circlecenter-radius;
Paint.setstrokewidth (This.roundwidth);
Invalidate (); /** * Ring Diameter * * @param circlewidth diameter/public void setcirclewidth (int circlewidth) {this.circlewidth = CI
Rclewidth;
Circlecenter = CIRCLEWIDTH/2;
if (Roundwidth > Circlecenter) {roundwidth = Circlecenter;
} setroundwidth (Roundwidth);
Sweepgradient = new Sweepgradient (THIS.CIRCLEWIDTH/2, THIS.CIRCLEWIDTH/2, colors, null);
Rotate it or it starts at 0 degrees. Matrix matrix = new Matrix ();
Matrix.setrotate ( -90, THIS.CIRCLEWIDTH/2, THIS.CIRCLEWIDTH/2);
Sweepgradient.setlocalmatrix (matrix); /** * Gradient initialization */public void Sweepgradientinit () {//Gradient color sweepgradient = new Sweepgradient (THIS.CIRCLEWIDTH/2
, THIS.CIRCLEWIDTH/2, colors, null);
Rotate it or it starts at 0 degrees. Matrix matrix = new Matrix ();
Matrix.setrotate ( -90, THIS.CIRCLEWIDTH/2, THIS.CIRCLEWIDTH/2); SweepGradient.setlocalmatrix (matrix);
public void Initview () {circlecenter = circlewidth/2;//radius singlpoint = (float) 360/(float) maxcolornumber; RADIUS = (int) (CIRCLECENTER-ROUNDWIDTH/2);
Radius of the Ring sweepgradientinit ();
Mpainttext = new Paint ();
Mpainttext.setcolor (TextColor);
Mpainttext.settextalign (Paint.Align.CENTER);
Mpainttext.settextsize (TEXTSIZE);
Mpainttext.setantialias (TRUE);
Paint = new paint ();
Paint.setcolor (Roundbackgroundcolor);
Paint.setstyle (Paint.Style.STROKE);
Paint.setstrokewidth (Roundwidth);
Paint.setantialias (TRUE); The bounds of the shape and size of the arc used to define oval = new RECTF (Circlecenter-radius, Circlecenter-radius, Circlecenter + radius, Circlecenter +
RADIUS);
} @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas);
Background gradient color paint.setshader (sweepgradient);
Canvas.drawarc (Oval, -90, (float) (Progress * 3.6), false, paint);
Paint.setshader (NULL);
is the line mode if (!isline) {float start = -90f; float p = ((FloaT) Maxcolornumber/(float) 100);
p = (int) (progress * p);
for (int i = 0; i < p i++) {paint.setcolor (roundbackgroundcolor); Canvas.drawarc (Oval, start + Singlpoint-linewidth, LineWidth, false, paint);
Drawing interval Fast start = (start + singlpoint);
}//Draw the remaining blank area paint.setcolor (Roundbackgroundcolor);
Canvas.drawarc (Oval, -90, (float) (-(100-progress) * 3.6), false, paint); Draw a text scale for (int i = 1; I <= i++) {canvas.save ();//Save the current canvas canvas.rotate (360/10 * I, Circlecenter, circ
Lecenter);
Canvas.drawtext (i * + "", Circlecenter, Circlecenter-radius + ROUNDWIDTH/2 + getdpvalue (4) + TEXTSIZE, mPaintText);
Canvas.restore ()//}} Onprogressscore Onprogressscore;
public interface Onprogressscore {void Setprogressscore (float score);
} public synchronized void setprogress (final float p) {progress = P;
Postinvalidate (); }/** * @param p */public synchronized void setprogress (final float p, Onprogressscore ONPROgressscore) {this.onprogressscore = Onprogressscore;
progress = P;
Postinvalidate (); }
}
The above is a small set to introduce the Android custom circle with the scale gradient of the progress bar, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!