Android自定義View之自定義屬性
在Android開發中經常會用到自定義View的情況,而在自定義View時,自定義屬性是必須用到的。
1、新建一個自定義View如CustomView
它的自定義屬性主要是通過declare-styleable標籤為其配置自定義屬性。具體做法是:在res/values/目錄下增加一個resources xml檔案,示例如下(res/values/attrs.xml)(屬性值如字型、顏色、大小等需要傳遞到程式碼中獲取並使用)
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CustomView"> <attr name="textString" format="string"/> <attr name="colorValue" format="color"/> <attr name="textSize" format="dimension"/> </declare-styleable> </resources>
在attrs.xml檔案中,外層引入瞭如下標籤:
<declare-styleable name="CustomView">
解釋:
所有resources檔案中宣告的屬性都會在R.attr類中生成對應的成員變數:
public final class R{ public static final class attr{ public static final int textString=0x7f010038; public static final int colorValue=0x7f010039; public static final int textSize=0x7f010040; } }
但是宣告在標籤中的屬性,系統還會在R.styleable類中生成相關的成員變數
public static final class styleable{ public static final int[] CustomView={ 0x7f010038,0x7f010039,0x7f010040 }; public static final int CustomView_textString=0; public static final int CustomView_colorValue=1; public static final int CustomView_textSize=2; }
可以看出R.styleable.CustomView是一個陣列,其中的元素值恰好就是R.attr.textString~textSize的值。而下面的CustomView_textString~CustomView_textSize正好就是其對應的索引。
2、編寫佈局檔案,引用自定義的View
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/BgColor"
<com.example.CustomView
android:id="@+id/customView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:colorValue="@color/textRed"
app:textString="This is the Custom View!!"
app:textSize="21sp"
/>
</LinearLayout>
注意:
新增佈局檔案的名稱空間
因為我們自定義了View,並且自定義了屬性,而這些屬性不再屬於
http://schema.adnroid.com/apk/res/android
這個名稱空間屬於:
http://schema.android.com/apk/res/[你的專案包名]
所以需要在增加的佈局檔案中的名稱空間改成:
http://schema.adnroid.com/apk/res/com.example
關於自定義View的程式碼,會在下一篇文章中介紹,這裡主要是介紹自定義屬性的細節。
format的定義及應用示例:
1、reference:資源引用
屬性定義:
<attr name="background" format="reference"/>
使用示例:
<com.example.CustomView
android:layout_width="24dp"
android:layout_height="24dp"
app:background="@mipmap/bg"
/>
2、color:顏色值
屬性定義:
<attr name="textColor" format="color"/>
使用示例:
<com.example.CustomView
android:layout_width="24dp"
android:layout_height="24dp"
app:textColor="#000000"
/>
3、boolean:布林值
屬性定義:
<attr name="focusable" format="boolean"/>
使用示例:
<com.example.CustomView
android:layout_width="24dp"
android:layout_height="24dp"
app:foucusable="true"
/>
4、dimension:尺寸值
屬性定義:
<attr name="custonWidth" format="demension"/>
屬性使用:
<com.example.CustomView
app:customWidth="24dp"
android:layout_height="wrap_content"
/>
5、float:浮點值
屬性定義:
<attr name="fromAlpha" format="float"/>
屬性使用:
<com.example.CustomView
android:layout_width
android:layout_height
app:fromAlpha="0.5"
/>
6、integer:整型值
屬性定義:
<attr name="frameDuration" format="integer"/>
屬性使用:
<com.example.CustomView
app:frameDuration="12"
/>
7、string:字串
屬性定義:
<attr name="textString" format="string"/>
屬性使用:
<com.example.CustomView
app:textString="hello world!!"
/>
8、fraction:百分數
屬性定義:
<attr name="pivotX" format="fraction"/>
屬性使用:
<com.example.CustomView
app:pivotX="30%"
/>
9、列舉值
屬性定義:
<attr name="orientation">
<enum name="horizontal" value="0"/>
<enum name="vertical" value="1"/>
</attr>
屬性使用:
<com.example.CustomView
app:orientation="vertical"
/>
10、flag:位或運算子
屬性定義:
<declare-styleable name="CustomView">
<attr name="windowSoftInputMode">
<flag name = "stateUnspecified" value = "0" />
<flag name = "stateUnchanged" value = "1" />
<flag name = "stateHidden" value = "2" />
<flag name = "stateAlwaysHidden" value = "3" />
<flag name = "stateVisible" value = "4" />
<flag name = "stateAlwaysVisible" value = "5" />
<flag name = "adjustUnspecified" value = "0x00" />
<flag name = "adjustResize" value = "0x10" />
<flag name = "adjustPan" value = "0x20" />
<flag name = "adjustNothing" value = "0x30" />
</attr>
</declare-styleable>
屬性使用:
<com.example.CustomView
app:windowSoftInputMode="stateUnspecified|stateUnchanged|stateHidden"
/>
補充:
(2018-12-12)
在程式碼構造器中引用時需要注意TypedArray、AttributeSet這兩個點,例如:
public CustomView(Context context){
this(context,null);
}
public CustomView(Context context,AttributeSet attrs){
this(context,attrs,0);
}
public CustomView(Context context,AttributeSet attrs,int defStyleAttr){
super(context,attrs,defStyleAttr);
TypedArray array=context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomView,defStyleAttr);
int count=array.getIndexCount();
for(int i=0;i<count;i++){
switch(i){
case R.styleable.CustomView_attrs_text://宣告:在styleable中它的名字為attrs_text
text=array.getString(index);
break;
case R.styleable.CustomView_attrs_text_color:
texcolor=array.getInt(index,Color.BLACK);
break;
case R.styleable.CustomView_attrs_text_size:
textsize=array.getDimensionPixelSize(index16);
break;
......
}
關於TypedArray和AttributeSet
AttributeSet的作用就是在控制元件進行初始化的時候,解析佈局檔案中該控制元件的屬性(keyeg:background)與該值(valueeg:@drawable/icon)的資訊封裝在AttributeSet中,傳遞給該控制元件的建構函式。
對於非Android自帶的屬性,在View類中處理時是無法識別的,需要我們自己解析。所以需要用到TypedArray。在AttributeSet中有屬性名稱和屬性值,TypedArray的工作就是來告訴控制元件哪個屬性代表什麼意思。
TypedArray物件封裝了/values/attrs.xml中的styleable裡定義的每個屬性的型別資訊,通過TypedArray就可以知道AttributeSet中封裝的值的型別,從而可以對這些資料進行應用。