Let's take a look at the iOS Sesame Credit score screen.
This is the effect I do, or a little gap
Payment Treasure 9.9 version of Sesame Credit score Realization
First initializes various brushes, the default size
, padding
and small dots.
(Because really can't find the original sesame credit with dot blur effect of small dots, so have to use this instead)
The default size of view is DefaultSize = dp2px (250);
Default padding Size arcdistance = dp2px (14);
Outer ring Brush Mmiddlearcpaint = new Paint (Paint.anti_alias_flag);
Mmiddlearcpaint.setstrokewidth (8);
Mmiddlearcpaint.setcolor (Color.White);
Mmiddlearcpaint.setstyle (Paint.Style.STROKE);
Mmiddlearcpaint.setalpha (80);
Inner-layer Circle Brush minnerarcpaint = new Paint (Paint.anti_alias_flag);
Minnerarcpaint.setstrokewidth (30);
Minnerarcpaint.setcolor (Color.White);
Minnerarcpaint.setalpha (80);
Minnerarcpaint.setstyle (Paint.Style.STROKE);
Positive middle Font brush Mtextpaint = new Paint (Paint.anti_alias_flag);
Mtextpaint.setcolor (Color.White);
Mtextpaint.settextalign (Paint.Align.CENTER);
Ring Large scale brush mcalibrationpaint = new Paint (Paint.anti_alias_flag);
Mcalibrationpaint.setstrokewidth (4);
Mcalibrationpaint.setstyle (Paint.Style.STROKE);
Mcalibrationpaint.setcolor (Color.White);
Mcalibrationpaint.setalpha (120);
Ring Small scale brush msmallcalibrationpaint = new Paint (Paint.anti_alias_flag);
Msmallcalibrationpaint.setstrokewidth (1); Msmallcalibrationpaint.setstyLe (Paint.Style.STROKE);
Msmallcalibrationpaint.setcolor (Color.White);
Msmallcalibrationpaint.setalpha (130);
Circle Tick Text Brush mcalibrationtextpaint = new Paint (Paint.anti_alias_flag);
Mcalibrationtextpaint.settextsize (30);
Mcalibrationtextpaint.setcolor (Color.White);
Outer progress Brush Marcprogresspaint = new Paint (Paint.anti_alias_flag);
Marcprogresspaint.setstrokewidth (8);
Marcprogresspaint.setcolor (Color.White);
Marcprogresspaint.setstyle (Paint.Style.STROKE);
Marcprogresspaint.setstrokecap (Paint.Cap.ROUND);
Outer ring Small dot bitmap brush mbitmappaint = new Paint ();
Mbitmappaint.setstyle (Paint.Style.FILL);
Mbitmappaint.setantialias (TRUE);
Initialize small dot picture bitmap = Bitmapfactory.decoderesource (Getresources (), r.drawable.ic_circle);
The actual position of the current point pos = new float[2];
The tangent value of the current point is tan = new float[2]; Matrix = new Matrix ();
The code is very simple, is a variety of initialization, look down.
View
The measurement is mainly warp_content
given a default width-height value when giving the setting.
@Override
protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {
setmeasureddimension ( Resolvemeasure (Widthmeasurespec, defaultsize),
resolvemeasure (Heightmeasurespec, defaultsize));
Measure public
int resolvemeasure (int measurespec, int defaultsize) {
int = 0
) based on the values passed in int specsize = measurespec.getsize (measurespec);
Switch (Measurespec.getmode (measurespec))
{case
measurespec.unspecified: result
= defaultsize;
break;
Case Measurespec.at_most:
//Set the default value when setting warp_content
= Math.min (specsize, defaultsize);
break;
Case measurespec.exactly:
//setting math_parent and setting a fixed width-high value break
;
Default: Result
= defaultsize;
}
return result;}
Then determine View
the wide-height callback method.
@Override
protected void onsizechanged (int w, int h, int oldw, int oldh) {
super.onsizechanged (W, H, OLDW, OLDH);
width = W;
Height = h;
radius = WIDTH/2;
Outer ring Rectangle
mmiddlerect = new RECTF (defaultpadding, defaultpadding,width-defaultpadding, height-defaultpadding); c8/>//inner-layer ring rectangle
minnerrect = new RECTF (defaultpadding + arcdistance, defaultpadding + arcdistance,width- Defaultpadding-arcdistance, height-defaultpadding-arcdistance);
Outer progress Rectangle
mmiddleprogressrect = new RECTF (defaultpadding, defaultpadding,width-defaultpadding, Height- defaultpadding);
}
Here is the rectangular implementation required to initialize the arc, and the bottom starts with the focus, drawing,
Draw the outer arc, very simple, the angle of the beginning of the arc, angle.
private void Drawmiddlearc (Canvas Canvas) {
Canvas.drawarc (mmiddlerect, Mstartangle, Mendangle, False, mmiddlearcpaint);
}
Draw Inner Arc
private void Drawinnerarc (Canvas Canvas) {
Canvas.drawarc (minnerrect, Mstartangle, Mendangle, False, minnerarcpaint);
}
Draw the small scale on the inner arc, the canvas rotates to the beginning of the lower left corner of the arc, calculates the starting point of each tick mark, the whole arc is 210 degrees,
Draw a tick mark every 6 angles.
private void Drawsmallcalibration (Canvas Canvas) {
//rotate canvas
canvas.save ();
Canvas.rotate ( -105, radius, radius);
Calculates the start point of the tick mark
int startdst = (int) (defaultpadding + arcdistance-minnerarcpaint.getstrokewidth ()/2-1);
int ENDDST = (int) (STARTDST + minnerarcpaint.getstrokewidth ());
for (int i = 0; I <= i++) {
//6 degrees per rotation to draw a small scale
canvas.drawline (radius, startdst, radius, ENDDST, MSMALLCALIBR Ationpaint);
Canvas.rotate (6, radius, radius);
}
Canvas.restore ();
}
Draw the large scale on the inner arc, 350, 550, 600,650, 700, 950, corresponding credit score,
Rotate the canvas, calculate the starting point of tick marks, calculate the angle of each rotation, rotate every 35 degrees, and then draw the corresponding large tick marks.
It then draws the corresponding text content, uses paint
the measureText
method to measure the text the length, in turn draws the corresponding text content.
private void Drawcalibrationandtext (Canvas Canvas) {
//rotate the canvas to draw the corresponding scale
canvas.save ();
Canvas.rotate ( -105, radius, radius);
Calculates the start point of the tick mark
int startdst = (int) (defaultpadding + arcdistance-minnerarcpaint.getstrokewidth ()/2-1);
int ENDDST = (int) (STARTDST + minnerarcpaint.getstrokewidth ());
Scale rotation angle
int rotateangle = 210/10;
for (int i = 1; i < i++) {
if (i% 2!= 0)
{
canvas.drawline (radius, startdst, radius, ENDDST, McAli brationpaint);
}
Measure the length of the text
float Textlen = Mcalibrationtextpaint.measuretext (Sesamestr[i-1]);
Canvas.drawtext (Sesamestr[i-1], RADIUS-TEXTLEN/2, ENDDST +, mcalibrationtextpaint);
Canvas.rotate (Rotateangle, radius, radius);
}
Canvas.restore ();}
Draw the middle of the credit score, credit rating, evaluation time and other text, this relatively simple, direct drawText
, in order to arrange the high and low.
private void Drawcentertext (Canvas Canvas) {
//Draw logo
mtextpaint.settextsize ();
Canvas.drawtext ("BETA", radius, radius-130, mtextpaint);
Draw credit score
mtextpaint.settextsize (m);
Mtextpaint.setstyle (Paint.Style.STROKE);
Canvas.drawtext (String.valueof (mminnum), radius, radius + mtextpaint);
Draw the credit level
mtextpaint.settextsize ();
Canvas.drawtext (sesamelevel, radius, radius + 160, mtextpaint);
Draw the evaluation time
mtextpaint.settextsize (m);
Canvas.drawtext (evaluationtime, radius, radius + 205, mtextpaint);
}
Draw the outermost progress, which is used here to Path
add the arc to be drawn, because you need to continue to compute the coordinates, the main use of PathMeasure
this class, the drawn arc into the path
middle,
The actual position of the current point
private float[] pos;
The current tangent value
private float[] tan;
Gets the tangent and coordinates of the end point of the path, and then draws the dots based on the coordinate point
Pathmeasure pathmeasure = new Pathmeasure (path, false);
Pathmeasure.getpostan (Pathmeasure.getlength () * 1, POS, tan);
private void Drawringprogress (Canvas Canvas) {
path Path = new Path ();
Path.addarc (Mmiddleprogressrect, Mstartangle, mcurrentangle);
Pathmeasure pathmeasure = new Pathmeasure (path, false);
Pathmeasure.getpostan (Pathmeasure.getlength () * 1, POS, tan);
Matrix.reset ();
Matrix.posttranslate (Pos[0]-bitmap.getwidth ()/2, Pos[1]-bitmap.getheight ()/2);
Canvas.drawpath (path, marcprogresspaint);
The starting angle is not 0 time to draw the dot
if (Mcurrentangle = = 0) return
;
Canvas.drawbitmap (bitmap, Matrix, mbitmappaint);
Mbitmappaint.setcolor (color.white);
Canvas.drawcircle (Pos[0], pos[1], 8, mbitmappaint);
OK, here's all finished, let's move the arc progress bar, using valueanimator
, the progress bar animation defines the starting angle of the Arc progress bar mcurrentangle
, ARC angle mtotalangle
, numeric animation defines the initialization of minnum=0
, and Maxnum
is evaluated based on the values passed in.
public void Startanim () {
Valueanimator Mangleanim = valueanimator.offloat (Mcurrentangle, mtotalangle);
Mangleanim.setinterpolator (New Acceleratedecelerateinterpolator ());
Mangleanim.setduration (3000);
Mangleanim.addupdatelistener (New Valueanimator.animatorupdatelistener () {
@Override public
Void Onanimationupdate (Valueanimator valueanimator) {
mcurrentangle = (float) valueanimator.getanimatedvalue ();
Postinvalidate ();
}
);
Mangleanim.start ();
Valueanimator Mnumanim = Valueanimator.ofint (Mminnum, mmaxnum);
Mnumanim.setduration (3000);
Mnumanim.setinterpolator (New Linearinterpolator ());
Mnumanim.addupdatelistener (New Valueanimator.animatorupdatelistener () {
@Override public
Void Onanimationupdate (Valueanimator valueanimator) {
mminnum = (int) valueanimator.getanimatedvalue ();
Postinvalidate ();
}
);
Mnumanim.start ();}
Finally, according to the incoming credit score to calculate the angle of the arc progress bar.
public void setsesamevalues (int values) {if (values <=) {mmaxnum = values;
Mtotalangle = 0f;
Sesamelevel = "Poor credit";
Evaluationtime = "Evaluation time:" + getcurrenttime ();
else if (values <=) {mmaxnum = values;
Mtotalangle = (values-350) * 80/400f + 2;
Sesamelevel = "Poor credit";
Evaluationtime = "Evaluation time:" + getcurrenttime ();
else if (values <=) {mmaxnum = values;
if (values >, && values <=) {sesamelevel = "Credit Medium";
else if (Values > && values <= 650) {sesamelevel = "good credit";
else {sesamelevel = "excellent credit";
} Mtotalangle = (values-550) * 120/150f + 43;
Evaluationtime = "Evaluation time:" + getcurrenttime ();
else if (values <= 950) {mmaxnum = values;
Mtotalangle = (values-700) * 40/250f + 170;
Sesamelevel = "excellent credit";
Evaluationtime = "Evaluation time:" + getcurrenttime ();
} else{mtotalangle = 240f;
} startanim (); }
Summarize
This article only analyzes the new version of the implementation process, the old version of the implementation of the same idea, the code is not complex. I hope this article will help you to develop Android, if you have any questions, you can exchange messages.