手把手教你自定義attr


      最近在學習的過程中遇到了自定義的attr和自定義的style。因此各種百度,各種博客的學習,算是有了一個系統的了解。在這里記錄下自己的收獲。

一、為什么要使用自定義attr以及本文定位

    在android開發中,很多時候需要我們自定義view,這其中就包含了一個view的很多屬性的設置。有時候會出現android本身提供的屬性並不夠用(比如它針對某些控件提供的text屬性,color屬性等),又或者我們想將android系統提供的屬性集成到一起形成自己的一套屬性集合。那么這個時候,就需要我們來自定義一套自己的屬性,這就是自定義attr。因此自定義attr與自定義view是密切關聯的。對於自定義attr更加深入的理解,在這里推薦我十分佩服的一位大神的博客文章http://blog.csdn.net/lmj623565791/article/details/45022631

    但是建議你還是閱讀完本文,再去點擊上面的鏈接。因為本文將手把手帶你去實現一個自定義的attr,這樣子你會了解整個自定義attr流程。既然是手把手,所以本文不會涉及到原理性的東西,而且代碼十分簡單易懂,因為我也是初學者,所以力求將一個初學者學習的過程展現出來,當然其中的某些疑問可能對於anroid老鳥來說是十分幼稚的。不過知識就是這樣子一點點一步步收獲起來的。好了,廢話不多說,進入正文吧。

二、你必須要了解的

    首先實現一個自定義attr的流程:

(1)先有一個自定義的view(它是你所自定義attr的使用者)

(2)然后在values文件夾下建立attrs.xml文件,編寫你的自定義的屬性。示例代碼如下:

1  <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3 
4     <declare-styleable name="test">
5         <attr name="text" format="string" />
6         <attr name="testAttr" format="integer" />
7     </declare-styleable>
8 
9 </resources>

 

(3)在xml文件中使用自定義屬性,為它賦值

(4)在自定義view中使用TypedArray獲取你所賦的值,並用作其他用途。

      

     現在主要說明編寫自定義屬性的代碼中,即上面的xml文件中,format的含義。其實format就是為自定義的屬性設置一個格式。這根android給我們提供的屬性是一樣的道理,比如android給我們提供的text的屬性格式就是string類型的,在我們為一個TextView設置text的時候可不就是寫一個字符串嘛。那么上面的代碼的意思就是自定義的屬性text,格式是string類型,testAttr,類型是integer。下面來看一個format都可以指定為什么。如下:

format還可以指定其他的類型比如;
reference   表示引用,參考某一資源ID
string   表示字符串
color   表示顏色值
dimension   表示尺寸值
boolean   表示布爾值
integer   表示整型值
float   表示浮點值
fraction   表示百分數
enum   表示枚舉值
flag   表示位運算

 

      可能還還有其他的疑問,比如其他關鍵字的含義是什么,以及是怎么使用自定義attr的。甚至還有很細的說不清的疑問。如果沒有實際代碼的話,很難說明白這些疑問。所以跟着我來往下一步一步寫一個例子出來吧,在這個過程中,相信你的疑問應該會被解開。

三、實現自定義attr,同時解答細節上的疑問    

      在這個例子中,我們來實現超級簡單的自定義view,在屏幕上寫用畫筆寫出一個字符串出來。純粹是為了說明自定義attr的實現過程的。而字符串的顏色以及字符串的內容,就采用自定義屬性的方式來獲取。我們心中已經有了這個自定義的view的大概了,下面就開始編寫自定義attr吧。

      新建項目,然后在它的res/values下面新建attrs.xml文件,代碼如下:

1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3      <declare-styleable name="MyView">  
4         <attr name="myText" format="string"/>  
5         <attr name="myColor" format="color"/>  
6     </declare-styleable>  
7 </resources>

      從代碼中我們可以看到,自定義了兩個屬性,myText和myColor,類型分別為string何color。然后要說明兩點:

(1)你可以將declare-styleable看成一個集合的名稱,而它里面的元素就是我們自定義的屬性。它可以命名為任意名稱,不過一般都命名為相應的自定義的view的名稱,表示是為這個view定制的屬性,也方便查閱。在這里我隨便命名了一個名字,為MyView。通過這個名稱就可以找到我們自定義的屬性。resources標簽下可以有多個declare-styleable的。
(2)標簽attr下的name就是自定義的屬性名,可以任意命名,format為其格式類型。

     你肯定還在疑問,自定義的屬性都自定義好了,怎么用呢?那么我們現在就來使用它。首先將與之相關的自定義的view先建出來。新建類CustomView繼承自view,代碼如下:

 1 package com.fuly.kun;
 2 
 3 import android.content.Context;
 4 
 5 import android.view.View;
 6 
 7 public class CustomView extends View {
 8     
 9     public CustomView(Context context, AttributeSet attrs) {
10         super(context, attrs);
11         
12     }
13     
14 }

      代碼很簡單,在這個自定義的view中,我們什么都沒有做。這個view肯定是要顯示出來的,那么我就修改activity_main.xml的代碼,將其顯示出來。注意這個時候,就該為CustomView設定屬性了,此時就開始使用自定義的attr了。好了,快看代碼吧,代碼:

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     xmlns:fuly="http://schemas.android.com/apk/res/com.fuly.kun"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6    >
 7 
 8    <com.fuly.kun.CustomView
 9        android:layout_width="wrap_content"
10        android:layout_height="wrap_content"
11        fuly:myText="我是自定義attr"
12        fuly:myColor="#00ff00"/>
13 </RelativeLayout>

      代碼很簡單,我們給自定義的view賦了屬性值。是不是發現了什么,有些代碼跟你之前用的不一樣!下面我們就來詳細說明一下怎么就把自定義的屬性給使用進來了。如下說明:

(1)首先觀察代碼的第3行,這句話就是引入了我們項目中自定義的attr。是不是發現第三行和第一行的代碼很像,其實你現在明白了吧,第一行其實就是因為android系統給出的屬性,所以下面我們才能使用android:layout_width等。因為引入自定義attr,主要將后綴的android替換成為項目的包名即可,即替換為了Manifest.xml下的package標簽下的包名。而我們將引入的自定義attr命名為了fuly,然后在使用自定義屬性時就借助fuly來找到我們自定義的屬性名稱了。fuly這個名稱可以隨便指定,沒有什么規則。
(2)再觀察第11行和第12行的代碼,跟第9行和第10行的代碼是不是很像,這就是在CustomView使用自定義的屬性,並為其賦值(一定要注意和其格式類型要相同)。

      好了,現在要修改CustomView的代碼了。獲取到我們自定義的屬性值,並使用它。這其實跟android獲取自帶的屬性是一樣的道理,比如我們給一個TextView的text賦了一個字符串,然后在代碼中使用getText()方法就可以這個字符串,即給text所賦的屬性值。好了,快看代碼吧,如下:

 1 package com.fuly.kun;
 2 
 3 import android.content.Context;
 4 import android.content.res.TypedArray;
 5 import android.graphics.Canvas;
 6 import android.graphics.Paint;
 7 import android.util.AttributeSet;
 8 import android.view.View;
 9 
10 public class CustomView extends View {
11     
12     private TypedArray ta;//用來獲取自定義屬性的
13     
14 
15     public CustomView(Context context, AttributeSet attrs) {
16         super(context, attrs);
17         //獲取到我們自定義的屬性
18         ta = context.obtainStyledAttributes(attrs, R.styleable.MyView);
19     }
20     
21     protected void onDraw(Canvas canvas) {
22 
23         super.onDraw(canvas);
24         //獲取到我們為自定義的屬性所賦的值
25         String text = ta.getString(R.styleable.MyView_myText);
26         int color = ta.getColor(R.styleable.MyView_myColor, 003300);
27         
28         Paint paint = new Paint();
29         paint.setColor(color);
30         paint.setTextSize(55);
31         canvas.drawText(text, 100, 100, paint);
32     }
33 
34 }

       代碼很簡單。只不過就牽涉了一個知識點,獲取自定義屬性的值,要使用TypedArray這個類而已。在代碼的第18行,我們獲取了一個TypedArray實例,而且這個實例是跟我們自定義的屬性集合MyView相關聯的。然后再代碼的第25和26行,就可以用這個TypedArray對象獲取自定義屬性的值了。注意ta.getColor的第二個參數意思是如果該屬性沒有賦值,就返回顏色“#003300”。然后我們將獲取到的文本和顏色作用到畫筆和畫布上即可。

      好了,MainActivtity中的代碼已經加載了acitivty_main.xml布局,不需要更改。下面我們直接運行效果,如下:

 

小結:

主要是TypedArray的對象的獲得,是通過Context的,如下:
 ta = context.obtainStyledAttributes(attrs, R.styleable.MyView);

關於它的一系列方法,可以翻看API文檔,這里總結沒有什么意義。

 

      好了,相信對自定義attr有了一個初步的了解了吧。以后程序開發中要比這個里復雜的多。學習進階,不要怕難,貴在堅持!一起進步

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM