生活随笔
收集整理的這篇文章主要介紹了
Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載請注明地址:http://blog.csdn.net/xiaanming/article/details/10298163
很多的時候,系統自帶的View滿足不了我們功能的需求,那么我們就需要自己來自定義一個能滿足我們需求的View,自定義View我們需要先繼承View,添加類的構造方法,重寫父類View的一些方法,例如onDraw,為了我們自定義的View在一個項目中能夠重用,有時候我們需要自定義其屬性,舉個很簡單的例子,我在項目中的多個界面使用我自定義的View,每個界面該自定義View的顏色都不相同,這時候如果沒有自定義屬性,那我們是不是需要構建不同顏色的View出來呢,這樣子我們的代碼就會顯得很沉厄,所以這時候我們就需要自定義其屬性來滿足我們不同的需求,自定義屬性呢,我們需要在values下建立attrs.xml文件,在其中定義我們需要定義的屬性,然后在自定義View中也要做相對應的修改,我們還是用一個小例子來看看自定義View和自定義屬性的使用
?
今天帶大家來自己定義一個帶進度的圓形進度條,我們還是先看一下效果吧
從上面可以看出,我們可以自定義圓環的顏色,圓環進度的顏色,是否顯示進度的百分比,進度百分比的顏色,以及進度是實心還是空心等等,這樣子是不是很多元化很方便呢?接下來我們就來教大家怎么來定義
?
1.在values下面新建一個attrs.xml,現在里面定義我們的屬性,不同的屬性對應不同的format,屬性對應的format可以參考http://blog.csdn.net/pgalxx/article/details/6766677,介紹的還是比較詳細,接下來我貼上我在自定義這個進度條所用到的屬性
?
[html]?view plaincopy
<?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>??
2.自定義View的屬性我們算是定義好了,接下來就是怎么獲取屬性和代碼的編寫了,我們需要在構造方法中獲取我們自己定義的相關屬性,我們先調用context.obtainStyledAttributes(attrs,R.styleable.RoundProgressBar)來獲取TypedArray,然后從TypedArray獲取我們定義的屬性,例如
?
?
[java]?view plaincopy
roundColor?=?mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor,?Color.RED);??????????roundProgressColor?=?mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor,?Color.GREEN);??????????textColor?=?mTypedArray.getColor(R.styleable.RoundProgressBar_textColor,?Color.GREEN);??????????textSize?=?mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize,?15);??????????roundWidth?=?mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth,?5);??????????max?=?mTypedArray.getInteger(R.styleable.RoundProgressBar_max,?100);??????????textIsDisplayable?=?mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable,?true);??????????style?=?mTypedArray.getInt(R.styleable.RoundProgressBar_style,?0);?? 上面的代碼中,如roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED); getColor方法的第一個參數是我們在XML文件中定義的顏色,如果我們沒有給我們自定義的View定義顏色,他就會使用第二個參數中的默認值,即Color.RED
?
?
3.為了方便大家理解,我將自定義View的全部代碼貼出來,里面的代碼我也有詳細的注釋
?
[java]?view plaincopy
package?com.example.roundprogressbar;????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.util.Log;??import?android.view.View;????import?com.example.circlepregress.R;????public?class?RoundProgressBar?extends?View?{??????????private?Paint?paint;????????????????private?int?roundColor;????????????????private?int?roundProgressColor;????????????????private?int?textColor;????????????????private?float?textSize;????????????????private?float?roundWidth;????????????????private?int?max;????????????????private?int?progress;??????????private?boolean?textIsDisplayable;????????????????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);????????????????????????????roundColor?=?mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor,?Color.RED);??????????roundProgressColor?=?mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor,?Color.GREEN);??????????textColor?=?mTypedArray.getColor(R.styleable.RoundProgressBar_textColor,?Color.GREEN);??????????textSize?=?mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize,?15);??????????roundWidth?=?mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth,?5);??????????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();??????}??????????????@Override??????protected?void?onDraw(Canvas?canvas)?{??????????super.onDraw(canvas);????????????????????????????int?centre?=?getWidth()/2;?????????int?radius?=?(int)?(centre?-?roundWidth/2);?????????paint.setColor(roundColor);?????????paint.setStyle(Paint.Style.STROKE);?????????paint.setStrokeWidth(roundWidth);?????????paint.setAntiAlias(true);??????????canvas.drawCircle(centre,?centre,?radius,?paint);???????????????????Log.e("log",?centre?+?"");????????????????????????????paint.setStrokeWidth(0);???????????paint.setColor(textColor);??????????paint.setTextSize(textSize);??????????paint.setTypeface(Typeface.DEFAULT_BOLD);?????????int?percent?=?(int)(((float)progress?/?(float)max)?*?100);??????????float?textWidth?=?paint.measureText(percent?+?"%");?????????????????????if(textIsDisplayable?&&?percent?!=?0?&&?style?==?STROKE){??????????????canvas.drawText(percent?+?"%",?centre?-?textWidth?/?2,?centre?+?textSize/2,?paint);?????????}????????????????????????????????????????????????????????paint.setStrokeWidth(roundWidth);?????????paint.setColor(roundProgressColor);??????????RectF?oval?=?new?RectF(centre?-?radius,?centre?-?radius,?centre??????????????????+?radius,?centre?+?radius);????????????????????switch?(style)?{??????????case?STROKE:{??????????????paint.setStyle(Paint.Style.STROKE);??????????????canvas.drawArc(oval,?0,?360?*?progress?/?max,?false,?paint);??????????????break;??????????}??????????case?FILL:{??????????????paint.setStyle(Paint.Style.FILL_AND_STROKE);??????????????if(progress?!=0)??????????????????canvas.drawArc(oval,?0,?360?*?progress?/?max,?true,?paint);??????????????break;??????????}??????????}????????????????}??????????????????public?synchronized?int?getMax()?{??????????return?max;??????}????????????public?synchronized?void?setMax(int?max)?{??????????if(max?<?0){??????????????throw?new?IllegalArgumentException("max?not?less?than?0");??????????}??????????this.max?=?max;??????}????????????public?synchronized?int?getProgress()?{??????????return?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;??????}????????}??
4.通過上面幾步我們就實現了自定義View,和自定義View的屬性,當然使用過程中還是有一點變化,我們必須在界面布局的最頂層加上
?
?xmlns:android_custom="http://schemas.Android.com/apk/res/com.example.circlepregress"這個即命名空間,
?
- 紅色部分是自定義屬性的前綴,什么意思呢?對于android系統控件我們定義其控件屬性是用android:XXX="XXXXXXX",而我們自己定義的就用android_custom:XXX = "XXXXXX"
- 綠色部分則是我們的包的名字
?
通過上面這兩步我們就能自己定義屬性了,我貼出自定義View在XML中使用情況
?
[java]?view plaincopy
<RelativeLayout?xmlns:android="http://schemas.android.com/apk/res/android"????????xmlns:android_custom="http://schemas.android.com/apk/res/com.example.circlepregress"??????xmlns:tools="http://schemas.android.com/tools"????????android:layout_width="match_parent"????????android:layout_height="match_parent"?>????????????????<com.example.roundprogressbar.RoundProgressBar????????????android:id="@+id/roundProgressBar2"????????????android:layout_width="80dip"????????????android:layout_height="80dip"????????????android:layout_alignLeft="@+id/roundProgressBar1"????????????android:layout_alignParentBottom="true"????????????android:layout_marginBottom="78dp"????????????????????????????????????android_custom:roundColor="#D1D1D1"????????????android_custom:roundProgressColor="@android:color/black"????????????android_custom:textColor="#9A32CD"????????????android_custom:textIsDisplayable="false"????????????android_custom:roundWidth="10dip"????????????android_custom:textSize="18sp"/>????</RelativeLayout>??? ?
?
?
今天就到此結束,如果大家有什么疑問,請留言,我會及時回復大家的
?
項目源碼,點擊下載
?
from:?http://blog.csdn.net/xiaanming/article/details/10298163
總結
以上是生活随笔為你收集整理的Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。