Background Introduction
In Android development, we often encounter a variety of gorgeous controls, so, relying on our Android itself with the control is not enough, many times we need to define our own control, in the development process, our company encountered a need to write a custom band progress of the round progress bar, Looks very gorgeous, of course, there are some other, such as: the wave shape of the circular progress bar and other effects are very nice. If any friend has realized, hoped to share, I also good study study. Well, not to mention, next, we'll look at how to achieve a circular progress bar.
Original address: http://blog.csdn.net/xiaanming/article/details/10298163
one: first.
Two: Instance code1. Custom Attributes
<?xml version= "1.0" encoding= "Utf-8"?><resources> <declare-styleable name= "Roundprogressbar" > <attr name= "roundcolor" format= "color"/> <attr name= "roundprogresscolor" format= "Color"/> <attr name= "Roundwidth" format= "Dimension" ></attr> <attr name= "textcolor" format= "COLOR"/ > <attr name= "textSize" format= "Dimension"/> <attr name= "max" format= "integer" ></attr > <attr name= "Textisdisplayable" format= "boolean" ></attr> <attr name= "Style" > <enum name= "STROKE" value= "0" ></enum> <enum name= "FILL" value= "1" ></enum> </ Attr> </declare-styleable></resources>
PS: Custom properties, in fact, we may not quite understand, some small partners may know that I use this, you can call it a value, you can get the value, or give a value, such as: You use the Android system itself with the control, TextView other, you know he has height , Width,textsize,textcolor, and so on, these attributes, you can assign value, but have to understand how to get the value, if not understand, it's OK, I have a more detailed in the Hon Yang wrote, recommended to you:http://blog.csdn.net/lmj623565791/article/details/45022631, still waiting for what, hurriedly poke in, take you pretend to take you fly.
2. Custom Control Source Code 1:
Package Com.example.testdemo.view;import Android.annotation.suppresslint;import Android.content.context;import Android.content.res.typedarray;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.graphics.rectf;import Android.graphics.typeface;import Android.util.attributeset;import android.view.view;import com.example.testdemo.r;/** * Fake iphone with progress bar, thread-safe view, Progress can be updated directly in the thread * * @author Zengtao May 12, 2015 PM 7:43:32 * * */@SuppressLint ("Drawallocation") public class Roundprogressbar ex Tends View {/** * Brush object reference */private Paint paint;/** * ring color */private int roundcolor;/** * Ring progress color */private int Roundprog resscolor;/** * Middle Progress percent of the string color */private int textcolor;/** * Middle Progress percentage of the font */private float textsize;/** * Ring width */private Float roundwidth;/** * Max Progress */private int max;/** * Current Progress */private int progress;/** * Show Intermediate Progress */private Boolean TEXTISD isplayable;/** * Progress style, solid or hollow */private int style;public static final int STROKE = 0;public Static final int FILL = 1;public Roundprogressbar (context context) {This (context, null);} Public Roundprogressbar (context context, AttributeSet Attrs) {This (context, attrs, 0);} Public Roundprogressbar (context context, AttributeSet attrs, int defstyle) {Super (context, Attrs, defstyle);p aint = new Pa int (); TypedArray Mtypedarray = context.obtainstyledattributes (Attrs, R.styleable.roundprogressbar);// Get custom properties and default values Roundcolor = Mtypedarray.getcolor (R.styleable.roundprogressbar_roundcolor, Color.rgb (228, 232, 237)); Roundprogresscolor = Mtypedarray.getcolor (R.styleable.roundprogressbar_roundprogresscolor, Color.rgb (216, 6, 7)); TextColor = Mtypedarray.getcolor (R.styleable.roundprogressbar_textcolor, Color.rgb (216, 6, 7)); textSize = Mtypedarray.getdimension (r.styleable.roundprogressbar_textsize); roundwidth = Mtypedarray.getdimension ( R.styleable.roundprogressbar_roundwidth, 3); max = Mtypedarray.getinteger (R.styleable.roundprogressbar_max, 100); textisdisplayable = Mtypedarray.getboolean (R.STYLEABLE.ROundprogressbar_textisdisplayable, true); style = Mtypedarray.getint (r.styleable.roundprogressbar_style, 0); Mtypedarray.recycle ();} @Overrideprotected void OnDraw (canvas canvas) {super.ondraw (canvas);/** * 1. Draw the outermost large ring */int centre = getwidth ()/2;//Get the Circle The x-coordinate of the heart int radius = (int) (CENTRE-ROUNDWIDTH/2); The radius of the ring Paint.setcolor (Roundcolor); Sets the color of the ring Paint.setstyle (Paint.Style.STROKE); Set Hollow Paint.setstrokewidth (Roundwidth); Sets the width of the ring Paint.setantialias (true); Anti-aliasing canvas.drawcircle (centre, centre, RADIUS, paint); Draw the Ring/** * 2. Draw Progress Percentage */paint.setstrokewidth (0);p Aint.setcolor (textcolor);p aint.settextsize (textSize); Paint.settypeface (Typeface.default); Set the font//middle progress percentage, first converted to float for division, otherwise 0int percent = (int) ((float) progress/(FLOAT) max) *, float textWidth = PA Int.measuretext (Percent + "%"); To measure the font width, we need to set the font width in the middle of the ring if (textisdisplayable && style = = STROKE) {Canvas.drawtext (percent + "%", centre-te XTWIDTH/2, centre + TEXTSIZE/2, paint); Draw a progress percentage}/** * 3. Drawing arcs, draw the progress of the ring *///set the progress is solid or hollow paint.setstrokewidth (roundwidth); Sets the width of the ring Paint.setcolor (Roundprogresscolor); Set the color of the progress RECTF oval = new RECTF (Centre-radius, Centre-radius, centre + RADIUS, centre + radius); Bounds for defining the shape and size of the arc switch (style) {case STROKE: {paint.setstyle (Paint.Style.STROKE); Canvas.drawarc (Oval,-90, 360 * Progress/max, false, paint); Draw arc break according to progress;} Case FILL: {paint.setstyle (Paint.Style.FILL_AND_STROKE); if (progress! = 0) Canvas.drawarc (Oval, -90, Progress/max, True, paint); Draw arc break according to progress;}}} public synchronized int Getmax () {return max;} /** * Set the maximum progress value * * @param max */public synchronized void Setmax (int max) {if (Max < 0) {throw new Illegalargumentexcep tion ("Max not less than 0");} This.max = max;} /** * Get progress. Need to sync * * @return */public synchronized int getprogress () {return progress;} /** * Set Progress, this is a thread-safe control, due to the problem of multi-line, need synchronous Refresh interface Call Postinvalidate () can refresh in non-UI thread * * @param progress */public synchronized void Setprog Ress (int progress) {if (Progress < 0) {throw new ILlegalargumentexception ("Progress not less than 0");} if (Progress > Max) {progress = max;} if (Progress <= max) {this.progress = Progress;postinvalidate ();}} public int Getcriclecolor () {return roundcolor;} public void Setcriclecolor (int criclecolor) {this.roundcolor = Criclecolor;} public int Getcricleprogresscolor () {return roundprogresscolor;} public void Setcricleprogresscolor (int cricleprogresscolor) {this.roundprogresscolor = Cricleprogresscolor;} public int GetTextColor () {return textcolor;} public void SetTextColor (int textcolor) {this.textcolor = TextColor;} public float GetTextSize () {return textSize;} public void Settextsize (float textSize) {this.textsize = textSize;} public float Getroundwidth () {return roundwidth;} public void Setroundwidth (float roundwidth) {this.roundwidth = Roundwidth;} public int GetStyle () {return style;} public void SetStyle (int style) {this.style = style;}}
Source 2:
Package Com.example.testdemo.view;import Android.annotation.suppresslint;import Android.content.context;import Android.content.res.typedarray;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.graphics.rectf;import Android.graphics.typeface;import Android.util.attributeset;import android.view.view;import com.example.testdemo.r;/** * Fake iphone with progress bar, thread-safe view, Progress can be updated directly in the thread * * @author Zengtao May 12, 2015 PM 7:43:32 * * */@SuppressLint ("Drawallocation") public class RoundProgressBar2 E Xtends View {/** * Brush object reference */private Paint paint;/** * ring color */private int roundcolor;/** * Ring progress color */private int Roundpro gresscolor;/** * Middle Progress percent of the string color */private int textcolor;/** * Middle Progress percentage of the font */private float textsize;/** * Ring width */privat e Float roundwidth;/** * max Progress */private int max;/** * Current Progress */private int progress;/** * Show Intermediate Progress */private Boolean Textis displayable;/** * Progress style, solid or hollow */private int style;public static final int STROKE = 0;public statIC final int FILL = 1;public RoundProgressBar2 (context context) {This (context, null);} Public RoundProgressBar2 (context context, AttributeSet Attrs) {This (context, attrs, 0);} Public RoundProgressBar2 (context context, AttributeSet attrs, int defstyle) {Super (context, Attrs, defstyle);p aint = new P Aint (); TypedArray Mtypedarray = context.obtainstyledattributes (Attrs, R.styleable.roundprogressbar);// Get custom properties and default values Roundcolor = Mtypedarray.getcolor (R.styleable.roundprogressbar_roundcolor, Color.rgb (228, 232, 237)); Roundprogresscolor = Mtypedarray.getcolor (R.styleable.roundprogressbar_roundprogresscolor, Color.rgb (216, 6, 7)); TextColor = Mtypedarray.getcolor (R.styleable.roundprogressbar_textcolor, Color.rgb (216, 6, 7)); textSize = Mtypedarray.getdimension (r.styleable.roundprogressbar_textsize); roundwidth = Mtypedarray.getdimension ( R.styleable.roundprogressbar_roundwidth, 3); max = Mtypedarray.getinteger (R.styleable.roundprogressbar_max, 100); textisdisplayable = Mtypedarray.getboolean (r.styleabLe. Roundprogressbar_textisdisplayable, true); style = Mtypedarray.getint (r.styleable.roundprogressbar_style, 0); Mtypedarray.recycle ();} @Overrideprotected void OnDraw (canvas canvas) {super.ondraw (canvas);/** * Draw the outermost large ring */int centre = getwidth ()/2;//Get Center of x-coordinate int radius = (int) (CENTRE-ROUNDWIDTH/2); The radius of the ring Paint.setcolor (Roundcolor); Sets the color of the ring Paint.setstyle (Paint.Style.STROKE); Set Hollow Paint.setstrokewidth (Roundwidth); Sets the width of the ring Paint.setantialias (true); Anti-aliasing canvas.drawcircle (centre, centre, RADIUS, paint); Draw a Circle/** * Draw Progress Percentage */paint.setstrokewidth (0);p Aint.setcolor (textcolor);p aint.settextsize (textSize); Paint.settypeface (Typeface.default); Set font//int percent = (int) ((float) progress/(FLOAT) max) * 100); The percentage of progress in the middle, first converted to float in the division operation, otherwise all for 0float textWidth = Paint.measuretext ("Rob"); To measure the font width, we need to set the font width in the middle of the ring if (textisdisplayable && style = = STROKE) {canvas.drawtext ("Rob", CENTRE-TEXTWIDTH/2 , centre + TEXTSIZE/2-4, paint); Draw a progress percentage}/** * Draw an arc, draw the progress of the ring */// Sets whether the progress is solid or hollow paint.setstrokewidth (roundwidth); Sets the width of the ring Paint.setcolor (Roundprogresscolor); Set the color of the progress RECTF oval = new RECTF (Centre-radius, Centre-radius, centre + RADIUS, centre + radius); Bounds for defining the shape and size of the arc switch (style) {case STROKE: {paint.setstyle (Paint.Style.STROKE); Canvas.drawarc (Oval,-90, 360 * Progress/max, false, paint); Draw arc break according to progress;} Case FILL: {paint.setstyle (Paint.Style.FILL_AND_STROKE); if (progress! = 0) Canvas.drawarc (Oval, -90, Progress/max, True, paint); Draw arc break according to progress;}}} public synchronized int Getmax () {return max;} /** * Set the maximum progress value * * @param max */public synchronized void Setmax (int max) {if (Max < 0) {throw new Illegalargumentexcep tion ("Max not less than 0");} This.max = max;} /** * Get progress. Need to sync * * @return */public synchronized int getprogress () {return progress;} /** * Set Progress, this is a thread-safe control, due to the problem of multi-line, need synchronous Refresh interface Call Postinvalidate () can refresh in non-UI thread * * @param progress */public synchronized void Setprog Ress (int progress) {if (Progress < 0) {throw new IllegalargumeNtexception ("Progress not less than 0");} if (Progress > Max) {progress = max;} if (Progress <= max) {this.progress = Progress;postinvalidate ();}} public int Getcriclecolor () {return roundcolor;} public void Setcriclecolor (int criclecolor) {this.roundcolor = Criclecolor;} public int Getcricleprogresscolor () {return roundprogresscolor;} public void Setcricleprogresscolor (int cricleprogresscolor) {this.roundprogresscolor = Cricleprogresscolor;} public int GetTextColor () {return textcolor;} public void SetTextColor (int textcolor) {this.textcolor = TextColor;} public float GetTextSize () {return textSize;} public void Settextsize (float textSize) {this.textsize = textSize;} public float Getroundwidth () {return roundwidth;} public void Setroundwidth (float roundwidth) {this.roundwidth = Roundwidth;}}
PS: Above two custom source code, actually you look carefully, the difference is not very big, changed a place, this change place, actually is in our present project encounters, therefore, does not have this circular control, I thought you will use later, is worth the collection.
three. Specific calls
Package Com.example.testdemo;import Android.annotation.suppresslint;import Android.app.activity;import Android.graphics.color;import Android.os.bundle;import Android.os.handler;import Android.os.Message;import Android.view.view;import Android.view.view.onclicklistener;import Android.widget.button;import Com.example.testdemo.view.roundprogressbar;import com.example.testdemo.view.roundprogressbar2;/** * Main interface * @author Zengtao June 10, 2015 PM 4:02:13 * */public class Mainactivity extends Activity {private RoundProgressBar2 r3;private Roundpro Gressbar R1, R2, R4, r5;private int pro1 = 80; The progress value that you want to display: Data returned from the server, such as project, private int progress = 0;private Boolean flag = false;private MyThread thread1;private MyThread2 Thread2;private Button start, @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate ( Savedinstancestate); Setcontentview (R.layout.activity_main); Initview (); Setroundattribute (); Can be set without setting}/** * Start method */private void Start () {//thread 1thread1 = new MyThread (); Thread1.start ();Thread 2thread2 = new MyThread2 (); Thread2.start ();} /** * Initialize control */private void Initview () {r1 = (Roundprogressbar) Findviewbyid (R.ID.PRPGRESS1); r2 = (Roundprogressbar) findVi Ewbyid (R.ID.PRPGRESS2); r3 = (ROUNDPROGRESSBAR2) Findviewbyid (R.ID.PRPGRESS3); r4 = (Roundprogressbar) Findviewbyid ( R.ID.PRPGRESS4); r5 = (Roundprogressbar) Findviewbyid (R.ID.PRPGRESS5); start = (Button) Findviewbyid (R.id.start); Start.setonclicklistener (listener);} /** * Set the properties of the Circle */private Void Setroundattribute () {r1.setroundwidth () R1.settextcolor (Color.parsecolor ("#00ff00")); R1.setcriclecolor (Color.parsecolor ("#ff0000")); R2.setroundwidth R2.settextcolor (Color.parsecolor ("#0000ff") ); R2.setcriclecolor (Color.parsecolor ("#ff00ff")); r4.setroundwidth; R4.settextcolor (Color.parsecolor ("# FF00FF "), R4.setcriclecolor (Color.parsecolor (" #ff0000 ")), R4.setstyle (0); R4.setroundwidth (R4.settextcolor); Color.parsecolor ("#000000")); R4.setcriclecolor (Color.parsecolor ("#ffff00")); R4.setstyle (1);} /** * Click event */onclicklistener ListeneR = new Onclicklistener () {@Overridepublic void OnClick (View v) {if (v = = start) {start ();}}};/ * * for updating UI */@SuppressLint ("Handlerleak") private Handler Mhandler = new Handler () {public void Handlemessage (Android.os. Message msg) {final int x = msg.what;final int temp = (int) msg.obj;if (x = = 0 * 1) {if (pro1-temp > 0) {r1.setprogre SS (temp); r2.setprogress (temp); r3.setprogress (temp); r4.setprogress (temp); r5.setprogress (temp);} else {r1.setprogress (Pro1); r2.setprogress (Pro1); r3.setprogress (Pro1); r4.setprogress (Pro1); r5.setprogress (Pro1); Thread1.stopthread ();}} else if (x = = 0 * 2) {if (pro1-temp > 0) {r1.setprogress (temp); r2.setprogress (temp); r3.setprogress (temp); R4.setprogre SS (temp); r5.setprogress (temp);} else {r1.setprogress (Pro1); r2.setprogress (Pro1); r3.setprogress (Pro1); r4.setprogress (Pro1); r5.setprogress (Pro1); Thread2.stopthread ();}}};};/ * * Thread, Control progress animation * @author Zengtao June 10, 2015 PM 4:31:11 * */class MyThread extends Thread {@Overridepublic void run () {while (!flag) {try {PROgress + = 1; Message msg = new Message (); msg.what = 0 * 1;msg.obj = progress; Thread.Sleep (+); mhandler.sendmessage (msg);} catch (Interruptedexception e) {e.printstacktrace ();}}} public void Stopthread () {flag = true;}} /** * Thread, Control progress animation * @author Zengtao June 10, 2015 PM 4:31:11 * */class MyThread2 extends thread {@Overridepublic void run () {WHI Le (!flag) {try {progress + = 2; Message msg = new Message (); msg.what = 0 * 2;msg.obj = progress; Thread.Sleep (+); mhandler.sendmessage (msg);} catch (Interruptedexception e) {e.printstacktrace ();}}} public void Stopthread () {flag = true;}} @Overrideprotected void OnDestroy () {Super.ondestroy (); if (thread1! = null) {Thread1.stopthread ();} if (thread2! = null) {Thread2.stopthread ();}}}
Four. SummaryBy implementing the above steps, you implement a secure and reliable custom control that looks simple and does not say minutes, but takes a little bit of time to make it yours.
Source: http://download.csdn.net/detail/u011546655/8793521
Advanced Android Player, custom circular progress bar