Android advanced, custom circular progress bar, and android advanced

Source: Internet
Author: User
Tags drawtext

Android advanced, custom circular progress bar, and android advanced
Background

In Android development, we often encounter a variety of beautiful controls. Therefore, relying on the controls provided by Android itself is far from enough. In many cases, we need to define our own controls, during the development process, our company encountered a circular progress bar that needs to be written by ourselves, which looks very brilliant. Of course there are some others, such: the watermarked circular progress bar and other effects are very nice. If any of you want to share it with me, I can learn from it. After that, let's take a look at how to implement the Circular progress bar.

Address: http://blog.csdn.net/xiaanming/article/details/10298163


I. go first



Ii. instance Code 1. 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: What about Custom Attributes? In fact, you may not understand it very well. Some friends may know that I can call a value to obtain a value or assign a value, for example, if you use the controls and textview that are included in the Android system, you know that the controls include height, width, textsize, and textcolor. You can assign values to these attributes, but have you ever understood how to get the value? If you don't know it, it doesn't matter. I have a more detailed article on Hongyang. I recommend it to you: Baidu.


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;/*** the progress of the iphone. Progress bar and thread-safe View. You can directly update the progress in the thread ** @ author zengtao 7:43:32, January 1, May 12, 2015 ***/@ SuppressLint ("DrawAllocation ") public class RoundProgressBar extends View {/*** Paint object reference */private paint Paint;/*** ring color */private int roundColor; /* the color of the ring progress */private int roundProgressColor;/* the color of the string with the intermediate progress percentage */private int textColor; /*** the font of the string with the intermediate progress percentage */private float textSize;/*** the width of the ring */private float roundWidth ;/** * Maximum progress */private int max;/* current progress */private int progress;/* Indicates whether to display the progress in the middle */private boolean textIsDisplayable; /*** 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); paint = new Paint (); TypedArray mTypedArray = context. obtainStyledAttributes (attrs, R. styleable. roundProgressBar); // get custom attributes and default value roundColor = mTypedArray. getColor (R. styleable. roundProgressBar_roundColor, Color. rgb (228,232,237); roundProgressColor = mTypedArray. getColor (R. styleable. roundProgressBar_roundProgressColor, Colo R. rgb (216, 6, 7); textColor = mTypedArray. getColor (R. styleable. roundProgressBar_textColor, Color. rgb (216, 6, 7); textSize = mTypedArray. getDimension (R. styleable. roundProgressBar_textSize, 18); roundWidth = mTypedArray. getDimension (R. styleable. roundProgressBar_roundWidth, 3); max = mTypedArray. getInteger (R. styleable. roundProgressBar_max, 100); textIsDisplayable = mTypedArray. getBoolean (R. styleable. rou NdProgressBar_textIsDisplayable, true); style = mTypedArray. getInt (R. styleable. roundProgressBar_style, 0); mTypedArray. recycle () ;}@ Overrideprotected void onDraw (Canvas canvas) {super. onDraw (canvas);/*** 1. draw the outermost ring */int center = getWidth ()/2; // obtain the x coordinate int radius = (int) (center-roundWidth/2) of the center ); // circle radius paint. setColor (roundColor); // set the color of the ring to paint. setStyle (Paint. style. STROKE); // set the hollow paint. setS TrokeWidth (roundWidth); // set the width of the ring to paint. setAntiAlias (true); // removes the Sawtooth canvas. drawCircle (center, center, radius, paint); // draw the ring/*** 2. painting progress percentage */paint. setStrokeWidth (0); paint. setColor (textColor); paint. setTextSize (textSize); paint. setTypeface (Typeface. DEFAULT); // set the font // progress percentage in the middle, first converted to float before division, otherwise all are 0int percent = (int) (float) progress/(float) max) * 100); float textWidth = paint. measureText (percen T + "%"); // measure the font width. We need to set the font width in the middle of the ring if (textIsDisplayable & style = STROKE) {canvas. drawText (percent + "%", center-textWidth/2, center + textSize/2, paint); // draw progress percentage}/*** 3. draw an arc and draw the progress of the ring * // set whether the progress is solid or hollow paint. setStrokeWidth (roundWidth); // set the ring width to paint. setColor (roundProgressColor); // set the progress color RectF oval = new RectF (center-radius, center-radius, center + radius, center + radius); // used Defines the arc shape and size boundaries switch (style) {case STROKE: {paint. setStyle (Paint. style. STROKE); canvas. drawArc (oval,-90,360 * progress/max, false, paint); // draw an arc break Based on the progress;} case FILL: {paint. setStyle (Paint. style. FILL_AND_STROKE); if (progress! = 0) canvas. drawArc (oval,-90,360 * progress/max, true, paint); // draw an arc break Based on the 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 IllegalArgumentException ("max not less than 0");} this. max = max;}/*** get progress. you need to synchronize ** @ return */public synchronized int getProgress () {return progress;}/*** to set the progress. This is a thread security control. Due to the multi-line problem, to synchronously refresh the interface, call postInvalidate () to refresh the ** @ param progress */public synchronized void setProgress (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 code 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;/*** the progress of the iphone. Progress bar and thread-safe View. You can directly update the progress in the thread ** @ author zengtao 7:43:32, January 1, May 12, 2015 ***/@ SuppressLint ("DrawAllocation ") public class RoundProgressBar2 extends View {/*** Paint object reference */private paint Paint;/*** ring color */private int roundColor; /* the color of the ring progress */private int roundProgressColor;/* the color of the string with the intermediate progress percentage */private int textColor; /*** font of the string with the intermediate progress percentage */private float textSize;/*** ring width */private float roundWidth ;/* ** Maximum progress */private int max;/*** current progress */private int progress;/*** whether to display the progress in the middle */private boolean textIsDisplayable; /*** 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 (Con Text context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); paint = new Paint (); TypedArray mTypedArray = context. obtainStyledAttributes (attrs, R. styleable. roundProgressBar); // get custom attributes and default value 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, 18); 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 ring */int center = getWidth ()/2; // obtain the x coordinate int radius = (int) of the center) (center-roundWidth/2); // circle radius paint. setColor (roundColor); // set the color of the ring to paint. setStyle (Paint. style. STROKE); // set the hollow paint. se TStrokeWidth (roundWidth); // set the ring width to paint. setAntiAlias (true); // removes the Sawtooth canvas. drawCircle (center, center, radius, paint); // draw the ring/*** painting progress percentage */paint. setStrokeWidth (0); paint. setColor (textColor); paint. setTextSize (textSize); paint. setTypeface (Typeface. DEFAULT); // set the font // int percent = (int) (float) progress/(float) max) * 100); // The progress percentage in the middle, convert to float before division. Otherwise, all values are 0 float textWidth = paint. measureText ("Grab"); // measure the font width. We need to set the font width in the middle of the ring if (textIsDisplayable & style = STROKE) {canvas. drawText ("grab", center-textWidth/2, center + textSize/2-4, paint); // draw progress percentage}/*** draw an arc, draw the progress of the ring * // set whether the progress is solid or hollow paint. setStrokeWidth (roundWidth); // set the ring width to paint. setColor (roundProgressColor); // set the progress color RectF oval = new RectF (center-radius, center-radius, center + radius, center + radius ); // defines 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 an arc break Based on the progress;} case FILL: {paint. setStyle (Paint. style. FILL_AND_STROKE); if (progress! = 0) canvas. drawArc (oval,-90,360 * progress/max, true, paint); // draw an arc break Based on the 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 IllegalArgumentException ("max not less than 0");} this. max = max;}/*** get progress. you need to synchronize ** @ return */public synchronized int getProgress () {return progress;}/*** to set the progress. This is a thread security control. Due to the multi-line problem, to synchronously refresh the interface, call postInvalidate () to refresh the ** @ param progress */public synchronized void setProgress (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: the above two custom source codes, in fact, you carefully look at, the difference is not very big, it changes a place, this change, in fact, this is what we have encountered in our current project. Therefore, if you cannot publish this circular control, I think you will use it in the future and it is worth adding to your favorites.

Iii. 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 4:02:13 **/public class MainActivity extends Activity {private RoundProgressBar2 r3; private RoundProgressBar r1, r2, r4, r5; private int pro1 = 80; // progress value to be displayed: for example, 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 (); // you can set it or not.}/*** start Method */private void start () {// thread 1thread1 = new MyThread (); thread1.start (); // thread 2thread2 = new MyThread2 (); thread2.start ();} /*** initialize the control */private void initView () {r1 = (RoundProgressBar) findViewById (R. id. prpgress1); r2 = (RoundProgressBar) findViewById (R. id. prpgress2); r3 = (R OundProgressBar2) 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 circle attribute */private void setRoundAttribute () {r1.setRoundWidth (10); r1.setTextColor (Color. parseColor ("#00ff00"); r1.setCricleColor (Color. parseColor ("# ff0000"); r2.setR OundWidth (20); r2.setTextColor (Color. parseColor ("# 0000ff"); r2.setCricleColor (Color. parseColor ("# ff00ff"); r4.setRoundWidth (20); r4.setTextColor (Color. parseColor ("# ff00ff"); r4.setCricleColor (Color. parseColor ("# ff0000"); r4.setStyle (0); r4.setRoundWidth (20); 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 ();}}}; /*** update 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.setProgress (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.setProgress (temp); r5.setProgress (temp);} else {r1.setProgress (pro1); r2.setProgress (pro1); r3.setProgress (pro1); r4.setProgress (p) Ro1); r5.setProgress (pro1); thread2.stopThread () ;}};};/*** thread, control progress animation * @ author zengtao June 10, 2015 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 (100); mHandler. sendMessage (msg);} catch (InterruptedException e) {e. printStackTrace () ;}} public void stopThread () {flag = true ;}}/*** thread, control progress animation * @ author zengtao June 10, 2015 4:31:11 **/class MyThread2 extends Thread {@ Overridepublic void run () {while (! Flag) {try {progress + = 2; Message msg = new Message (); msg. what = 0*2; msg. obj = progress; Thread. sleep (200); 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 ();}}}


4. the above steps are summarized to implement a secure and reliable custom control. It seems simple, not to mention minutes, but it is yours to take a moment.
Source code: http://download.csdn.net/detail/u011546655/8793521





Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.