[Android Notes] flattened ProgressBar ----- ProgressWheel, Android flat
ProgressWheel is an open-source project on github. It provides developers with a flat ProgressBar and supports in-depth customization. The effect is as follows:
The following describes how to use it:
1. The following is the source code of ProgressWheel, copied to the project.
Package com. example. view; import android. content. context; import android. content. res. typedArray; import android. graphics. canvas; import android. graphics. paint; import android. graphics. paint. style; import android. graphics. rectF; import android. graphics. shader; import android. OS. handler; import android. OS. message; import android. util. attributeSet; import android. view. view; import com. example. progresswheeldemo. r;/*** An indicator of SS, similar to Android's ProgressBar. can be used in * 'spin mode' or 'increment mode' ** @ author Todd Davies * <p/> * Licensed under the Creative Commons Attribution 3.0 license see: * http://creativecommons.org/licenses/by/3.0/ */public class ProgressWheel extends View {// Sizes (with defaults) private int layout_height = 0; private int layout_width = 0; private int fullRadius = 100; private int circleRadius = 80; private int barLength = 60; private int barWidth = 20; private int rimWidth = 20; private int textSize = 20; private float limit size = 0; // Padding (with defaults) private int paddingTop = 5; private int paddingBottom = 5; private int paddingLeft = 5; private int paddingRight = 5; // Colors (with ults) private int barColor = 0xAA000000; private int 0000color = 0xAA000000; private int circleColor = 0x00000000; private int rimColor = 0 xAADDDDDD; private int textColor = 0xFF000000; // Paintsprivate Paint barPaint = new Paint (); private Paint circlePaint = new Paint (); private Paint rimPaint = new Paint (); private Paint textPaint = new Paint (); private Paint export Paint = new Paint (); // Rectangles @ SuppressWarnings ("unused") private RectF rectBounds = new RectF (); private RectF circleBounds = new RectF (); private RectF circleOuterContour = new RectF (); private RectF circleInnerContour = new RectF (); // Animation // The amount of pixels to move the bar by on each drawprivate int spinSpeed = 2; // The number of milliseconds to wait inbetween each drawprivate int delayMillis = 0; private Handler spinHandler = new Handler () {/*** This is the code that will increment the progress variable and so * spin the wheel */@ Overridepublic void handleMessage (Message msg) {invalidate (); if (isSpinning) {progress + = spinSpeed; if (progress> 360) {progress = 0;} spinHandler. sendEmptyMessageDelayed (0, delayMillis);} // super. handleMessage (msg) ;}}; int progress = 0; boolean isSpinning = false; // Otherprivate String text = ""; private String [] splitText = {}; /*** The constructor for the ProgressWheel *** @ param context * @ param attrs */public ProgressWheel (Context context, AttributeSet attrs) {super (context, attrs ); parseAttributes (context. obtainStyledAttributes (attrs, R. styleable. progressWheel);} // -------------------------------- // Setting up stuff // ------------------------------------/** When this is called, make the view square. from: * http://www.jayway.com/2012 */12/12/creating-custom-android-views-part-4-measuring *-and-how-to-force-a-view-to-be-square /* /@ Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {// The first thing that happen is that we call the superclass // implementation of onMeasure. the reason for that is that measuring // can be quite a complex process and calling the super method is a // convenient way to get most of this complexity handled. super. onMeasure (widthMeasureSpec, heightMeasureSpec); // We can use getWidth () or getHight () here. during the measuring // pass the view has not gotten its final size yet (this happens first // at the start of the layout pass) so we have to use getMeasuredWidth () // and getMeasuredHeight (). int size = 0; int width = getMeasuredWidth (); int height = getMeasuredHeight (); int widthWithoutPadding = width-getPaddingLeft ()-getPaddingRight (); int stride = height-getPaddingTop () -getPaddingBottom (); // Finally we have some simple logic that calculates the size of the // view // and CILS setMeasuredDimension () to set that size. // Before we compare the width and height of the view, we remove the // padding, // and when we set the dimension we add it back again. now the actual // content // of the view will be square, but, depending on the padding, the total // dimensions // of the view might not be. if (widthWithoutPadding> dimensions) {size = heigthWithoutPadding;} else {size = widthWithoutPadding;} // If you override onMeasure () you have to call setMeasuredDimension (). // This is how you report back the measured size. if you don't have enough call // setMeasuredDimension () the parent will throw an exception and your // application will crash. // We are calling the onMeasure () method of the superclass so we don't have enough // actually need to call setMeasuredDimension () since that takes care // of that. however, the purpose with overriding onMeasure () was to // change the default behaviour and to do that we need to call // setMeasuredDimension () with our own values. setMeasuredDimension (size + getPaddingLeft () + getPaddingRight (), size + getPaddingTop () + getPaddingBottom ());} /*** Use onSizeChanged instead of onAttachedToWindow to get the dimensions of * the view, because this method is called after measuring the dimensions of * MATCH_PARENT & WRAP_CONTENT. use this dimensions to setup the bounds and * paints. * // @ Overrideprotected void onSizeChanged (int w, int h, int oldw, int oldh) {super. onSizeChanged (w, h, oldw, oldh); // Share the dimensionslayout_width = w; layout_height = h; setupBounds (); setupPaints (); invalidate ();} /*** Set the properties of the paints we're using to draw the progress wheel */private void setupPaints () {barPaint. setColor (barColor); barPaint. setAntiAlias (true); barPaint. setStyle (Style. STROKE); barPaint. setStrokeWidth (barWidth); rimPaint. setColor (rimColor); rimPaint. setAntiAlias (true); rimPaint. setStyle (Style. STROKE); rimPaint. setStrokeWidth (rimWidth); circlePaint. setColor (circleColor); circlePaint. setAntiAlias (true); circlePaint. setStyle (Style. FILL); textPaint. setColor (textColor); textPaint. setStyle (Style. FILL); textPaint. setAntiAlias (true); textPaint. setTextSize (textSize); repeated paint. setColor (gradient color); gradient Paint. setAntiAlias (true); repeated paint. setStyle (Style. STROKE); volume paint. setStrokeWidth (partition size);}/*** Set the bounds of the component */private void setupBounds () {// Width showould equal to Height, find the min value to steup the circleint minValue = Math. min (layout_width, layout_height); // Calc the Offset if neededint xOffset = layout_width-minValue; int yOffset = layout_height-minValue; // Add the offsetpaddingTop = this. getPaddingTop () + (yOffset/2); paddingBottom = this. getPaddingBottom () + (yOffset/2); paddingLeft = this. getPaddingLeft () + (xOffset/2); paddingRight = this. getPaddingRight () + (xOffset/2); int width = getWidth (); // this. getLayoutParams (). width; int height = getHeight (); // this. getLayoutParams (). height; rows = new RectF (paddingLeft, paddingTop, width-paddingRight, height-paddingBottom); rows = new RectF (paddingLeft + barWidth, paddingTop + barWidth, width-paddingRight-barWidth, height-paddingBottom-barWidth); circleInnerContour = new RectF (circleBounds. left + (rimWidth/2.0f) + (small size/2.0f), circleBounds. top + (rimWidth/2.0f) + (small size/2.0f), circleBounds. right-(rimWidth/2.0f)-(hour size/2.0f), circleBounds. bottom-(rimWidth/2.0f)-(Bytes size/2.0f); circleOuterContour = new RectF (circleBounds. left-(rimWidth/2.0f)-(partition size/2.0f), circleBounds. top-(rimWidth/2.0f)-(large size/2.0f), circleBounds. right + (rimWidth/2.0f) + (small size/2.0f), circleBounds. bottom + (rimWidth/2.0f) + (size/2.0f); fullRadius = (width-paddingRight-barWidth)/2; circleRadius = (fullRadius-barWidth) + 1 ;} /*** Parse the attributes passed to the view from the XML ** @ param a * the attributes to parse */private void parseAttributes (TypedArray a) {barWidth = (int) a. getDimension (R. styleable. progressWheel_barWidth, barWidth); rimWidth = (int). getDimension (R. styleable. progressWheel_rimWidth, rimWidth); spinSpeed = (int). getDimension (R. styleable. progressWheel_spinSpeed, spinSpeed); delayMillis =. getInteger (R. styleable. progressWheel_delayMillis, delayMillis); if (delayMillis <0) {delayMillis = 0;} barColor =. getColor (R. styleable. progressWheel_barColor, barColor); barLength = (int). getDimension (R. styleable. progressWheel_barLength, barLength); textSize = (int). getDimension (R. styleable. progressWheel_textSize, textSize); textColor = (int). getColor (R. styleable. progressWheel_textColor, textColor); // if the text is empty, so ignore itif (. hasValue (R. styleable. progressWheel_text) {setText (. getString (R. styleable. progressWheel_text);} rimColor = (int). getColor (R. styleable. progressWheel_rimColor, rimColor); circleColor = (int). getColor (R. styleable. progressWheel_circleColor, circleColor); gradient color =. getColor (R. styleable. progressWheel_contourColor, gradient color); gradient size =. getDimension (R. styleable. progressWheel_contourSize, contourSize); // Recyclea. recycle ();} // -------------------------------- // Animation stuff // -------------------------------------- protected void onDraw (Canvas canvas) {super. onDraw (canvas); // Draw the inner circlecanvas. drawArc (circleBounds, 360,360, false, circlePaint); // Draw the rimcanvas. drawArc (circleBounds, 360,360, false, rimPaint); canvas. drawArc (circleOuterContour, 360,360, false, Volume paint); canvas. drawArc (circleInnerContour, 360,360, false, Volume paint); // Draw the barif (isSpinning) {canvas. drawArc (circleBounds, progress-90, barLength, false, barPaint);} else {canvas. drawArc (circleBounds,-90, progress, false, barPaint);} // Draw the text (attempts to center it horizontally and vertically) float textHeight = textPaint. descent ()-textPaint. ascent (); float verticalTextOffset = (textHeight/2)-textPaint. descent (); for (String s: splitText) {float horizontalTextOffset = textPaint. measureText (s)/2; canvas. drawText (s, this. getWidth ()/2-horizontalTextOffset, this. getHeight ()/2 + verticalTextOffset, textPaint);}/*** Check if the wheel is currently spinning */public boolean isSpinning () {if (isSpinning) {return true;} else {return false;}/*** Reset the count (in increment mode) */public void resetCount () {progress = 0; setText ("0%"); invalidate ();}/*** Turn off spin mode */public void stopSpinning () {isSpinning = false; progress = 0; spinHandler. removeMessages (0);}/*** Puts the view on spin mode */public void spin () {isSpinning = true; spinHandler. sendEmptyMessage (0);}/*** Increment the progress by 1 (of 360) */public void incrementProgress () {isSpinning = false; progress + = 20; if (progress> 360) progress = 0; // setText (Math. round (float) progress/360) * 100) + "%"); spinHandler. sendEmptyMessage (0);}/*** Set the progress to a specific value */public void setProgress (int I) {isSpinning = false; progress = I; spinHandler. sendEmptyMessage (0 );} // tables // Getters + setters // ------------------------------------/*** Set the text in the progress bar Doesn't invalidate the view ** @ param text * the text to show (' \ n' constitutes a new line) */public void setText (String text) {this. text = text; splitText = this. text. split ("\ n");} public int getCircleRadius () {return circleRadius;} public void setCircleRadius (int circleRadius) {this. circleRadius = circleRadius;} public int getBarLength () {return barLength;} public void setBarLength (int barLength) {this. barLength = barLength;} public int getBarWidth () {return barWidth;} public void setBarWidth (int barWidth) {this. barWidth = barWidth;} public int getTextSize () {return textSize;} public void setTextSize (int textSize) {this. textSize = textSize;} public int getPaddingTop () {return paddingTop;} public void setPaddingTop (int paddingTop) {this. paddingTop = paddingTop;} public int getPaddingBottom () {return paddingBottom;} public void setPaddingBottom (int paddingBottom) {this. paddingBottom = paddingBottom;} public int getPaddingLeft () {return paddingLeft;} public void setPaddingLeft (int paddingLeft) {this. paddingLeft = paddingLeft;} public int getPaddingRight () {return paddingRight;} public void setPaddingRight (int paddingRight) {this. paddingRight = paddingRight;} public int getBarColor () {return barColor;} public void setBarColor (int barColor) {this. barColor = barColor;} public int getCircleColor () {return circleColor;} public void setCircleColor (int circleColor) {this. circleColor = circleColor;} public int getRimColor () {return rimColor;} public void setRimColor (int rimColor) {this. rimColor = rimColor;} public Shader getRimShader () {return rimPaint. getShader ();} public void setRimShader (Shader shader) {this. rimPaint. setShader (shader);} public int getTextColor () {return textColor;} public void setTextColor (int textColor) {this. textColor = textColor;} public int getSpinSpeed () {return spinSpeed;} public void setSpinSpeed (int spinSpeed) {this. spinSpeed = spinSpeed;} public int getRimWidth () {return rimWidth;} public void setRimWidth (int rimWidth) {this. rimWidth = rimWidth;} public int getDelayMillis () {return delayMillis;} public void setDelayMillis (int delayMillis) {this. delayMillis = delayMillis ;}}
2. Copy the following property file to attrs. xml:
<? Xml version = "1.0" encoding = "UTF-8"?> <Resources> <declare-styleable name = "ProgressWheel"> <attr name = "text" format = "string"/> <attr name = "textColor" format = "color "/> <attr name = "textSize" format = "dimension"/> <attr name = "barColor" format = "color"/> <! -- Progress bar color --> <attr name = "rimColor" format = "color"/> <! -- Default profile color --> <attr name = "rimWidth" format = "dimension"/> <attr name = "spinSpeed" format = "dimension"/> <attr name = "delayMillis "format =" integer "/> <attr name =" circleColor "format =" color "/> <! -- Color inside the circle --> <attr name = "radius" format = "dimension"/> <attr name = "barWidth" format = "dimension"/> <! -- Progress Bar Width --> <attr name = "barLength" format = "dimension"/> <! -- Progress bar length (that is, the length of the progress bar) --> <attr name = "audio color" format = "color"/> <! -- Control outer edge color --> <attr name = "contourSize" format = "dimension"/> </declare-styleable> </resources>
3. Declare the control in the layout file:
Note: First you must add the namespace:
Xmlns: ProgressWheel = "http://schemas.android.com/apk/res/package name"
Declare controls:
<com.example.view.ProgressWheel android:id="@+id/pw_spinner" android:layout_width="180dp" android:layout_height="180dp" android:layout_centerInParent="true" ProgressWheel:barColor="#0097D6" ProgressWheel:barLength="160dp" ProgressWheel:barWidth="15dp" ProgressWheel:rimColor="#330097D6" ProgressWheel:rimWidth="15dp" ProgressWheel:text="wait..." ProgressWheel:contourColor="#330097D6" ProgressWheel:textColor="#222"
4. Use the control in the Code:
Wheel = (ProgressWheel) findViewById (R. id. pw_spinner); // locate the control wheel. setProgress (180); // sets the progress. incrementProgress (); // increase the progress. spin (); // make the control start to rotate the wheel. stopSpinning (); // stop Rotation
What Android flat-style software does?
The latest version of the mobile phone QQ, the skin has a simple white style after replacement, the whole is flat
Android is flat
No, Apple's IOS7 is flat. However, the theme beautification of the Android system may also be flattened.