Android自定義View(二、深入解析自定義屬性)_第1頁
Android自定義View(二、深入解析自定義屬性)_第2頁
Android自定義View(二、深入解析自定義屬性)_第3頁
Android自定義View(二、深入解析自定義屬性)_第4頁
Android自定義View(二、深入解析自定義屬性)_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

付費(fèi)下載

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Android自定義View(二、深入解析自定義屬性)1.為什么要自定義屬性??要使用屬性,首先這個(gè)屬性應(yīng)該存在,所以如果我們要使用自己的屬性,必須要先把他定義出來才能使用。但我們平時(shí)在寫布局文件的時(shí)候好像沒有自己定義屬性,但我們照樣可以用很多屬性,這是為什么?我想大家應(yīng)該都知道:系統(tǒng)定義好的屬性我們就可以拿來用唄,但是你們知道系統(tǒng)定義了哪些屬性嗎?哪些屬性是我們自定義控件可以直接使用的,哪些不能使用?什么樣的屬性我們能使用?這些問題我想大家不一定都弄得清除,下面我們?nèi)ヒ灰唤忾_這些謎團(tuán)。??系統(tǒng)定義的所有屬性我們可以在\sdk\platforms\Android-xx\data\res\values目錄下找到attrs.xml這個(gè)文件,這就是系統(tǒng)自帶的所有屬性,打開看看一些比較熟悉的:<declare-styleablename="View"><attrname="id"format="reference"/><attrname="background"format="reference|color"/><attrname="padding"format="dimension"/>...<attrname="focusable"format="boolean"/>...</declare-styleable><declare-styleablename="TextView"><attrname="text"format="string"localization="suggested"/><attrname="hint"format="string"/><attrname="textColor"/><attrname="textColorHighlight"/><attrname="textColorHint"/>...</declare-styleable><declare-styleablename="ViewGroup_Layout"><attrname="layout_width"format="dimension"><enumname="fill_parent"value="-1"/><enumname="match_parent"value="-1"/><enumname="wrap_content"value="-2"/></attr><attrname="layout_height"format="dimension"><enumname="fill_parent"value="-1"/><enumname="match_parent"value="-1"/><enumname="wrap_content"value="-2"/></attr></declare-styleable><declare-styleablename="LinearLayout_Layout"><attrname="layout_width"/><attrname="layout_height"/><attrname="layout_weight"format="float"/><attrname="layout_gravity"/></declare-styleable><declare-styleablename="RelativeLayout_Layout"><attrname="layout_centerInParent"format="boolean"/><attrname="layout_centerHorizontal"format="boolean"/><attrname="layout_centerVertical"format="boolean"/>...</declare-styleable>看看上面attrs.xml文件中的屬性,發(fā)現(xiàn)他們都是有規(guī)律的分組的形式組織的。以declare-styleable為一個(gè)組合,后面有一個(gè)name屬性,屬性的值為View、TextView等等,有沒有想到什么?沒錯(cuò),屬性值為View的那一組就是為View定義的屬性,屬性值為TextView的就是為TextView定義的屬性…。??因?yàn)樗械目丶际荲iew的子類,所以為View定義的屬性所有的控件都能使用,這就是為什么我們的自定義控件沒有定義屬性就能使用一些系統(tǒng)屬性。??但是并不是每個(gè)控件都能使用所有屬性,比如TextView是View的子類,所以為View定義的所有屬性它都能使用,但是子類肯定有自己特有的屬性,得單獨(dú)為它擴(kuò)展一些屬性,而單獨(dú)擴(kuò)展的這些屬性只有它自己能有,View是不能使用的,比如View中不能使用android:text=“”。又比如,LinearLayout中能使用layout_weight屬性,而RelativeLayout卻不能使用,因?yàn)閘ayout_weight是為L(zhǎng)inearLayout的LayoutParams定義的。??綜上所述,自定義控件如果不自定義屬性,就只能使用VIew的屬性,但為了給我們的控件擴(kuò)展一些屬性,我們就必須自己去定義。2.怎樣自定義屬性??翻閱系統(tǒng)的屬性文件,你會(huì)發(fā)現(xiàn),有的這中形式,有的是;這兩種的區(qū)別就是attr標(biāo)簽后面帶不帶format屬性,如果帶format的就是在定義屬性,如果不帶format的就是在使用已有的屬性,name的值就是屬性的名字,format是限定當(dāng)前定義的屬性能接受什么值。??打個(gè)比方,比如系統(tǒng)已經(jīng)定義了android:text屬性,我們的自定義控件也需要一個(gè)文本的屬性,可以有兩種方式:第一種:我們并不知道系統(tǒng)定義了此名稱的屬性,我們自己定義一個(gè)名為text或者mText的屬性(屬性名稱可以隨便起的)<resources><declare-styleablename="MyTextView"><attrname=“text"format="string"/></declare-styleable></resources>第二種:我們知道系統(tǒng)已經(jīng)定義過名稱為text的屬性,我們不用自己定義,只需要在自定義屬性中申明,我要使用這個(gè)text屬性(注意加上android命名空間,這樣才知道使用的是系統(tǒng)的text屬性)<resources><declare-styleablename="MyTextView"><attrname=“android:text"/></declare-styleable></resources>??為什么系統(tǒng)定義了此屬性,我們?cè)谑褂玫臅r(shí)候還要聲明?因?yàn)椋到y(tǒng)定義的text屬性是給TextView使用的,如果我們不申明,就不能使用text屬性。3.屬性值的類型formatformat支持的類型一共有11種:(1).reference:參考某一資源ID屬性定義:<declare-styleablename="名稱"><attrname="background"format="reference"/></declare-styleable>屬性使用:<ImageViewandroid:background="@drawable/圖片ID"/>(2).color:顏色值屬性定義:<attrname="textColor"format="color"/>屬性使用:<TextViewandroid:textColor="#00FF00"/>(3).boolean:布爾值屬性定義:<attrname="focusable"format="boolean"/>屬性使用:<Buttonandroid:focusable="true"/>(4).dimension:尺寸值屬性定義:<attrname="layout_width"format="dimension"/>屬性使用:<Buttonandroid:layout_width="42dip"/>(5).float:浮點(diǎn)值屬性定義:<attrname="fromAlpha"format="float"/>屬性使用:<alphaandroid:fromAlpha="1.0"/>(6).integer:整型值屬性定義:<attrname="framesCount"format="integer"/>屬性使用:<animated-rotateandroid:framesCount="12"/>(7).string:字符串屬性定義:<attrname="text"format="string"/>屬性使用:<TextViewandroid:text="我是文本"/>(8).fraction:百分?jǐn)?shù)屬性定義:<attrname="pivotX"format="fraction"/>屬性使用:<rotateandroid:pivotX="200%"/>(9).enum:枚舉值屬性定義:<declare-styleablename="名稱"><attrname="orientation"><enumname="horizontal"value="0"/><enumname="vertical"value="1"/></attr></declare-styleable>屬性使用:<LinearLayoutandroid:orientation="vertical"></LinearLayout>注意:枚舉類型的屬性在使用的過程中只能同時(shí)使用其中一個(gè),不能android:orientation=“horizontal|vertical"(10).flag:位或運(yùn)算屬性定義:<declare-styleablename="名稱"><attrname="gravity"><flagname="top"value="0x30"/><flagname="bottom"value="0x50"/><flagname="left"value="0x03"/><flagname="right"value="0x05"/><flagname="center_vertical"value="0x10"/>...</attr></declare-styleable>屬性使用:<TextViewandroid:gravity="bottom|left"/>注意:位運(yùn)算類型的屬性在使用的過程中可以使用多個(gè)值(11).混合類型:屬性定義時(shí)可以指定多種類型值屬性定義:<declare-styleablename="名稱"><attrname="background"format="reference|color"/></declare-styleable>屬性使用:<ImageViewandroid:background="@drawable/圖片ID"/>或者:<ImageViewandroid:background="#00FF00"/>??通過上面的學(xué)習(xí)我們已經(jīng)知道怎么定義各種類型的屬性,以及怎么使用它們,但是我們寫好布局文件之后,要在控件中使用這些屬性還需要將它解析出來。4.類中獲取屬性值??在這之前,順帶講一下命名空間,我們?cè)诓季治募惺褂脤傩缘臅r(shí)候(android:layout_width="match_parent")發(fā)現(xiàn)前面都帶有一個(gè)android:,這個(gè)android就是上面引入的命名空間xmlns:android="/apk/res/android”,表示到android系統(tǒng)中查找該屬性來源。只有引入了命名空間,XML文件才知道下面使用的屬性應(yīng)該去哪里找(哪里定義的,不能憑空出現(xiàn),要有根據(jù))。??如果我們自定義屬性,這個(gè)屬性應(yīng)該去我們的應(yīng)用程序包中找,所以要引入我們應(yīng)用包的命名空間xmlns:openxu="/apk/res-auto”,res-auto表示自動(dòng)查找,還有一種寫法xmlns:openxu="/apk/com.example.openxu.myview",com.example.openxu.myview為我們的應(yīng)用程序包名。??按照上面學(xué)習(xí)的知識(shí),我們先定義一些屬性,并寫好布局文件。先在res\values目錄下創(chuàng)建attrs.xml,定義自己的屬性:<?xmlversion="1.0"encoding="utf-8"?><resources><declare-styleablename="MyTextView"><!--聲明MyTextView需要使用系統(tǒng)定義過的text屬性,注意前面需要加上android命名--><attrname="android:text"/><attrname="mTextColor"format="color"/><attrname="mTextSize"format="dimension"/></declare-styleable></resources>在布局文件中,使用屬性(注意引入我們應(yīng)用程序的命名空間,這樣在能找到我們包中的attrs):<LinearLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"xmlns:openxu="/apk/res-auto"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><com.example.openxu.myview.MyTextViewandroid:layout_width="200dip"android:layout_height="100dip"openxu:mTextSize="25sp"android:text="我是文字"openxu:mTextColor="#0000ff"android:background="#ff0000"/></LinearLayout>在構(gòu)造方法中獲取屬性值:publicMyTextView(Contextcontext,AttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);TypedArrayta=context.obtainStyledAttributes(attrs,R.styleable.MyTextView);Stringtext=ta.getString(R.styleable.MyTextView_android_text);intmTextColor=ta.getColor(R.styleable.MyTextView_mTextColor,Color.BLACK);intmTextSize=ta.getDimensionPixelSize(R.styleable.MyTextView_mTextSize,100);ta.recycle();//注意回收Log.v("openxu",“text屬性值:"+mText);Log.v("openxu","mTextColor屬性值:"+mTextColor);Log.v("openxu","mTextSize屬性值:"+mTextSize);}log輸出:05-2100:14:07.192:V/openxu(25652):mText屬性值:我是文字05-2100:14:07.192:V/openxu(25652):mTextColor屬性值:-1677696105-2100:14:07.192:V/openxu(25652):mTextSize屬性值:75到此為止,是不是發(fā)現(xiàn)自定義屬性是如此簡(jiǎn)單?屬性的定義我們應(yīng)該學(xué)的差不多了,但有沒有發(fā)現(xiàn)構(gòu)造方法中獲取屬性值的時(shí)候有兩個(gè)比較陌生的類AttributeSet和TypedArray,這兩個(gè)類是怎么把屬性值從布局文件中解析出來的?5.Attributeset和TypedArray以及declare-styleable??Attributeset看名字就知道是一個(gè)屬性的集合,實(shí)際上,它內(nèi)部就是一個(gè)XML解析器,幫我們將布局文件中該控件的所有屬性解析出來,并以key-value的兼職對(duì)形式維護(hù)起來。其實(shí)我們完全可以只用他通過下面的代碼來獲取我們的屬性就行。publicMyTextView(Contextcontext,AttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);intcount=attrs.getAttributeCount();for(inti=0;i<count;i++){StringattrName=attrs.getAttributeName(i);StringattrVal=attrs.getAttributeValue(i);Log.e("openxu","attrName="+attrName+",attrVal="+attrVal);}}log輸出:05-2102:18:09.052:E/openxu(14704):attrName=background,attrVal=@213142734705-2102:18:09.052:E/openxu(14704):attrName=layout_width,attrVal=200.0dip05-2102:18:09.052:E/openxu(14704):attrName=layout_height,attrVal=100.0dip05-2102:18:09.052:E/openxu(14704):attrName=text,attrVal=我是文字05-2102:18:09.052:E/openxu(14704):attrName=mTextSize,attrVal=25sp05-2102:18:09.052:E/openxu(14704):attrName=mTextColor,attrVal=#0000ff??發(fā)現(xiàn)通過Attributeset獲取屬性的值時(shí),它將我們布局文件中的值原原本本的獲取出來的,比如寬度200.0dip,其實(shí)這并不是我們想要的,如果我們接下來要使用寬度值,我們還需要將dip去掉,然后轉(zhuǎn)換成整形,這多麻煩。其實(shí)這都不算什么,更惡心的是,backgroud我應(yīng)用了一個(gè)color資源ID,它直接給我拿到了這個(gè)ID值,前面還加了個(gè)@,接下來我要自己獲取資源,并通過這個(gè)ID值獲取到真正的顏色。我們?cè)贀QTypedArray試試。??在這里,穿插一個(gè)知識(shí)點(diǎn),定義屬性的時(shí)候有一個(gè)declare-styleable,他是用來干嘛的,如果不要它可不可以?答案是可以的,我們自定義屬性完全可以寫成下面的形式:<?xmlversion="1.0"encoding="utf-8"?><resources><attrname="mTextColor"format="color"/><attrname="mTextSize"format="dimension"/></resources>之前的形式是這樣的:<?xmlversion="1.0"encoding="utf-8"?><resources><declare-styleablename="MyTextView"><attrname="android:text"/><attrname="android:layout_width"/><attrname="android:layout_height"/><attrname="android:background"/><attrname="mTextColor"format="color"/><attrname="mTextSize"format="dimension"/></declare-styleable></resources>或者:<?xmlversion="1.0"encoding="utf-8"?><resources><!--定義屬性--><attrname="mTextColor"format="color"/><attrname="mTextSize"format="dimension"/><declare-styleablename="MyTextView"><!--生成索引--><attrname="android:text"/><attrname="android:layout_width"/><attrname="android:layout_height"/><attrname="android:background"/><attrname=“mTextColor"/><attrname="mTextSize"/></declare-styleable></resources>??我們都知道所有的資源文件在R中都會(huì)對(duì)應(yīng)一個(gè)整型常亮,我們可以通過這個(gè)ID值找到資源文件。??屬性在R中對(duì)應(yīng)的類是publicstaticfinalclassattr,如果我們寫了declare-styleable,在R文件中就會(huì)生成styleable類,這個(gè)類其實(shí)就是將每個(gè)控件的屬性分組,然后記錄屬性的索引值,而TypedArray正好需要通過此索引值獲取屬性。publicstaticfinalclassstyleablepublicstaticfinalint[]MyTextView={0x0101014f,0x7f010038,0x7f010039};publicstaticfinalintMyTextView_android_text=0;publicstaticfinalintMyTextView_mTextColor=1;publicstaticfinalintMyTextView_mTextSize=2;}使用TypedArray獲取屬性值:publicMyTextView(Contextcontext,AttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);TypedArrayta=context.obtainStyledAttributes(attrs,R.styleable.MyTextView);StringmText=ta.getString(R.styleable.MyTextView_android_text);intmTextColor=ta.getColor(R.styleable.MyTextView_mTextColor,Color.BLACK);intmTextSize=ta.getDimensionPixelSize(R.styleable.MyTextView_mTextSize,100);floatwidth=ta.ge

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論