日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

發(fā)布時(shí)間:2025/3/20 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載請(qǐng)注明地址:http://blog.csdn.net/xiaanming/article/details/10298163

很多的時(shí)候,系統(tǒng)自帶的View滿足不了我們功能的需求,那么我們就需要自己來(lái)自定義一個(gè)能滿足我們需求的View,自定義View我們需要先繼承View,添加類的構(gòu)造方法,重寫父類View的一些方法,例如onDraw,為了我們自定義的View在一個(gè)項(xiàng)目中能夠重用,有時(shí)候我們需要自定義其屬性,舉個(gè)很簡(jiǎn)單的例子,我在項(xiàng)目中的多個(gè)界面使用我自定義的View,每個(gè)界面該自定義View的顏色都不相同,這時(shí)候如果沒有自定義屬性,那我們是不是需要構(gòu)建不同顏色的View出來(lái)呢,這樣子我們的代碼就會(huì)顯得很沉厄,所以這時(shí)候我們就需要自定義其屬性來(lái)滿足我們不同的需求,自定義屬性呢,我們需要在values下建立attrs.xml文件,在其中定義我們需要定義的屬性,然后在自定義View中也要做相對(duì)應(yīng)的修改,我們還是用一個(gè)小例子來(lái)看看自定義View和自定義屬性的使用

?

今天帶大家來(lái)自己定義一個(gè)帶進(jìn)度的圓形進(jìn)度條,我們還是先看一下效果吧

從上面可以看出,我們可以自定義圓環(huán)的顏色,圓環(huán)進(jìn)度的顏色,是否顯示進(jìn)度的百分比,進(jìn)度百分比的顏色,以及進(jìn)度是實(shí)心還是空心等等,這樣子是不是很多元化很方便呢?接下來(lái)我們就來(lái)教大家怎么來(lái)定義

?

1.在values下面新建一個(gè)attrs.xml,現(xiàn)在里面定義我們的屬性,不同的屬性對(duì)應(yīng)不同的format,屬性對(duì)應(yīng)的format可以參考http://blog.csdn.net/pgalxx/article/details/6766677,介紹的還是比較詳細(xì),接下來(lái)我貼上我在自定義這個(gè)進(jìn)度條所用到的屬性

?

[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的屬性我們算是定義好了,接下來(lái)就是怎么獲取屬性和代碼的編寫了,我們需要在構(gòu)造方法中獲取我們自己定義的相關(guān)屬性,我們先調(diào)用context.obtainStyledAttributes(attrs,R.styleable.RoundProgressBar)來(lái)獲取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方法的第一個(gè)參數(shù)是我們?cè)赬ML文件中定義的顏色,如果我們沒有給我們自定義的View定義顏色,他就會(huì)使用第二個(gè)參數(shù)中的默認(rèn)值,即Color.RED

    ?

    ?

    3.為了方便大家理解,我將自定義View的全部代碼貼出來(lái),里面的代碼我也有詳細(xì)的注釋

    ?

    [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;??
  • ??
  • /**?
  • ?*?仿iphone帶進(jìn)度的進(jìn)度條,線程安全的View,可直接在線程中更新進(jìn)度?
  • ?*?@author?xiaanming?
  • ?*?
  • ?*/??
  • public?class?RoundProgressBar?extends?View?{??
  • ????/**?
  • ?????*?畫筆對(duì)象的引用?
  • ?????*/??
  • ????private?Paint?paint;??
  • ??????
  • ????/**?
  • ?????*?圓環(huán)的顏色?
  • ?????*/??
  • ????private?int?roundColor;??
  • ??????
  • ????/**?
  • ?????*?圓環(huán)進(jìn)度的顏色?
  • ?????*/??
  • ????private?int?roundProgressColor;??
  • ??????
  • ????/**?
  • ?????*?中間進(jìn)度百分比的字符串的顏色?
  • ?????*/??
  • ????private?int?textColor;??
  • ??????
  • ????/**?
  • ?????*?中間進(jìn)度百分比的字符串的字體?
  • ?????*/??
  • ????private?float?textSize;??
  • ??????
  • ????/**?
  • ?????*?圓環(huán)的寬度?
  • ?????*/??
  • ????private?float?roundWidth;??
  • ??????
  • ????/**?
  • ?????*?最大進(jìn)度?
  • ?????*/??
  • ????private?int?max;??
  • ??????
  • ????/**?
  • ?????*?當(dāng)前進(jìn)度?
  • ?????*/??
  • ????private?int?progress;??
  • ????/**?
  • ?????*?是否顯示中間的進(jìn)度?
  • ?????*/??
  • ????private?boolean?textIsDisplayable;??
  • ??????
  • ????/**?
  • ?????*?進(jìn)度的風(fēng)格,實(shí)心或者空心?
  • ?????*/??
  • ????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);??
  • ??????????
  • ????????//獲取自定義屬性和默認(rèn)值??
  • ????????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);??
  • ??????????
  • ????????/**?
  • ?????????*?畫最外層的大圓環(huán)?
  • ?????????*/??
  • ????????int?centre?=?getWidth()/2;?//獲取圓心的x坐標(biāo)??
  • ????????int?radius?=?(int)?(centre?-?roundWidth/2);?//圓環(huán)的半徑??
  • ????????paint.setColor(roundColor);?//設(shè)置圓環(huán)的顏色??
  • ????????paint.setStyle(Paint.Style.STROKE);?//設(shè)置空心??
  • ????????paint.setStrokeWidth(roundWidth);?//設(shè)置圓環(huán)的寬度??
  • ????????paint.setAntiAlias(true);??//消除鋸齒???
  • ????????canvas.drawCircle(centre,?centre,?radius,?paint);?//畫出圓環(huán)??
  • ??????????
  • ????????Log.e("log",?centre?+?"");??
  • ??????????
  • ????????/**?
  • ?????????*?畫進(jìn)度百分比?
  • ?????????*/??
  • ????????paint.setStrokeWidth(0);???
  • ????????paint.setColor(textColor);??
  • ????????paint.setTextSize(textSize);??
  • ????????paint.setTypeface(Typeface.DEFAULT_BOLD);?//設(shè)置字體??
  • ????????int?percent?=?(int)(((float)progress?/?(float)max)?*?100);??//中間的進(jìn)度百分比,先轉(zhuǎn)換成float在進(jìn)行除法運(yùn)算,不然都為0??
  • ????????float?textWidth?=?paint.measureText(percent?+?"%");???//測(cè)量字體寬度,我們需要根據(jù)字體的寬度設(shè)置在圓環(huán)中間??
  • ??????????
  • ????????if(textIsDisplayable?&&?percent?!=?0?&&?style?==?STROKE){??
  • ????????????canvas.drawText(percent?+?"%",?centre?-?textWidth?/?2,?centre?+?textSize/2,?paint);?//畫出進(jìn)度百分比??
  • ????????}??
  • ??????????
  • ??????????
  • ????????/**?
  • ?????????*?畫圓弧?,畫圓環(huán)的進(jìn)度?
  • ?????????*/??
  • ??????????
  • ????????//設(shè)置進(jìn)度是實(shí)心還是空心??
  • ????????paint.setStrokeWidth(roundWidth);?//設(shè)置圓環(huán)的寬度??
  • ????????paint.setColor(roundProgressColor);??//設(shè)置進(jìn)度的顏色??
  • ????????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);??//根據(jù)進(jìn)度畫圓弧??
  • ????????????break;??
  • ????????}??
  • ????????case?FILL:{??
  • ????????????paint.setStyle(Paint.Style.FILL_AND_STROKE);??
  • ????????????if(progress?!=0)??
  • ????????????????canvas.drawArc(oval,?0,?360?*?progress?/?max,?true,?paint);??//根據(jù)進(jìn)度畫圓弧??
  • ????????????break;??
  • ????????}??
  • ????????}??
  • ??????????
  • ????}??
  • ??????
  • ??????
  • ????public?synchronized?int?getMax()?{??
  • ????????return?max;??
  • ????}??
  • ??
  • ????/**?
  • ?????*?設(shè)置進(jìn)度的最大值?
  • ?????*?@param?max?
  • ?????*/??
  • ????public?synchronized?void?setMax(int?max)?{??
  • ????????if(max?<?0){??
  • ????????????throw?new?IllegalArgumentException("max?not?less?than?0");??
  • ????????}??
  • ????????this.max?=?max;??
  • ????}??
  • ??
  • ????/**?
  • ?????*?獲取進(jìn)度.需要同步?
  • ?????*?@return?
  • ?????*/??
  • ????public?synchronized?int?getProgress()?{??
  • ????????return?progress;??
  • ????}??
  • ??
  • ????/**?
  • ?????*?設(shè)置進(jìn)度,此為線程安全控件,由于考慮多線的問(wèn)題,需要同步?
  • ?????*?刷新界面調(diào)用postInvalidate()能在非UI線程刷新?
  • ?????*?@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;??
  • ????}??
  • ??
  • ??
  • ??
  • }??

  • 4.通過(guò)上面幾步我們就實(shí)現(xiàn)了自定義View,和自定義View的屬性,當(dāng)然使用過(guò)程中還是有一點(diǎn)變化,我們必須在界面布局的最頂層加上

    ?

    ?xmlns:android_custom="http://schemas.Android.com/apk/res/com.example.circlepregress"這個(gè)即命名空間,

    ?

    • 紅色部分是自定義屬性的前綴,什么意思呢?對(duì)于android系統(tǒng)控件我們定義其控件屬性是用android:XXX="XXXXXXX",而我們自己定義的就用android_custom:XXX = "XXXXXX"
    • 綠色部分則是我們的包的名字

    ?

    通過(guò)上面這兩步我們就能自己定義屬性了,我貼出自定義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>???
  • ?

    ?

    ?

    今天就到此結(jié)束,如果大家有什么疑問(wèn),請(qǐng)留言,我會(huì)及時(shí)回復(fù)大家的

    ?

    項(xiàng)目源碼,點(diǎn)擊下載

    ?

    from:?http://blog.csdn.net/xiaanming/article/details/10298163

    總結(jié)

    以上是生活随笔為你收集整理的Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。