之前在自定義View理論中,遺留下了一個知識,就是具體的自定義屬性到底怎麼使用。本篇就對自定義屬性的常見方式,做詳細的整理。分析自定義屬性的常見三種方式。
我們知道,大部分情況我們的自定義View需要有更多的靈活性,比如我們在xml中指定了顏色大小等屬性,在程序運行時候控件就能展示出相應的顏色和大小。所以我們需要自定義屬性。我們還知道,當在佈局文件中加入某個控件的時候,會調用該View的構造方法 XXXView(Context context,AttributeSet attribute);當我們在 xml中創建了一個view時,xml會被解析,顯示解析用pull解析xml文件,解析成鍵值對,對象的封裝成AttributeSet 對象;根據元素名,有類的全名就可以反射實例化該類,得到AttributeSet 該類,就得到屬性值。我們只需要在這個參數中就可以獲取所有自定義的屬性值了。
如何自定義屬性?
在自定義屬性前,先看看系統是怎麼定義屬性的。(查看View類的屬性)
找到系統attrs目錄:
D:\prograssinstall\as\SDK\platforms\android-23\data\res\values,點擊打開。
看一下View類的屬性情況:
<declare-styleable name="View">
<!-- Supply an identifier name for this view, to later retrieve it
with {@link android.view.View#findViewById View.findViewById()} or
{@link android.app.Activity#findViewById Activity.findViewById()}.
This must be a
resource reference; typically you set this using the
<code>@+</code> syntax to create a new ID resources.
For example: <code>android:id="@+id/my_id"</code> which
allows you to later retrieve the view
with <code>findViewById(R.id.my_id)</code>. -->
<attr name="id" format="reference" />
<!-- Supply a tag for this view containing a String, to be retrieved
later with {@link android.view.View#getTag View.getTag()} or
searched for with {@link android.view.View#findViewWithTag
View.findViewWithTag()}. It is generally preferable to use
IDs (through the android:id attribute) instead of tags because
they are faster and allow for compile-time type checking. -->
<attr name="tag" format="string" />
<!-- The initial horizontal scroll offset, in pixels.-->
<attr name="scrollX" format="dimension" />
<!-- The initial vertical scroll offset, in pixels. -->
<attr name="scrollY" format="dimension" />
<!-- A drawable to use as the background. This can be either a reference
to a full drawable resource (such as a PNG image, 9-patch,
XML state list description, etc), or a solid color such as "#ff000000"
(black). -->
<attr name="background" format="reference|color" />
<!-- Sets the padding, in pixels, of all four edges. Padding is defined as
space between the edges of the view and the view's content. A views size
will include it's padding. If a {@link android.R.attr#background}
is provided, the padding will initially be set to that (0 if the
drawable does not have padding). Explicitly setting a padding value
will override the corresponding padding found in the background. -->
<attr name="padding" format="dimension" />
.........................................
拿<attr name="background" format="reference|color" />舉例,這裏制定了屬性名稱,以及該屬性的類型是引用類型和color類型。類型代表,我可以通過什麼方式給屬性賦值。比如我們通常設置背景可以這麼寫:background="@R.drawable/a.png";或者background="#ff0000".相信,看到這裏肯定能夠意會了吧。
細心的你,會發現每一個配置文件中有一行命名間:xmlns:Adroid="http://schemas.android.com/apk/res/android" 這是系統自帶的,它的原理是:通過命名空間的前綴android,找到包的信息(這裏是最後一個名稱android),通過包的信息,找到工程,找到工程後。就可以找到這個工程的資源信息(values----attrs屬性配置文件),從attrs文件裏找到屬性配置的信息。
瞭解了系統的定義屬性原理,我們開始自定屬性。標準的步驟如下:
1_創建工程:包名:com.itydl.a06attributetest
建議用UTF-8編碼
2_創建屬性類MyAttributeView繼承View
3_創建工程的屬性文件attrs.xml和常見屬性類型
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:itydl="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.itydl.a06attributetest.MainActivity">
<com.itydl.a06attributetest.MyAttributeView
itydl:my_age ="25dp"
itydl:my_name="android_attribute"
itydl:my_bg="@drawable/test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
其中itydl是自己的命名空間。
4_使用自定義類和自定義屬性
在res/values/下新建attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 定義一個名字叫MyAttributeView屬性集合,name往往跟對應的View的類名一致 -->
<declare-styleable name="MyAttributeView">
<!--定義一個類型爲integer,名字叫my_age的屬性 -->
<attr name="my_age" format="integer"/>
<!--定義一個類型爲string,名字叫my_name的屬性 -->
<attr name="my_name" format="string"/>
<!--定義一個類型爲reference和color(這樣背景可以通過R引用,
也可以使用圖片資源),名字叫my_bg的屬性 -->
<attr name="my_bg" format="reference|color"/>
</declare-styleable>
</resources>
5_三種方式得到屬性值
// 1.用命名空間取對應的屬性- String
String name = attrs.getAttributeValue(
"http://schemas.android.com/apk/res-auto",
"my_name");
String my_age = attrs.getAttributeValue(
"http://schemas.android.com/apk/res-auto",
"my_age");
String my_bg = attrs.getAttributeValue(
"http://schemas.android.com/apk/res-auto",
"my_bg");
// System.out.println(name+","+my_age+","+my_bg);
// 2.遍歷方式取屬性String 和int
for (int i = 0; i < attrs.getAttributeCount(); i++) {
System.out.println(attrs.getAttributeValue(i) + ":"
+ attrs.getAttributeName(i));
}
// 3.用系統工具TypedArray取屬性- 取各種值Bitmap String 等等
//參數1:自定義屬性集合類;參數2:自動生成的自定義屬性類名稱的資源id(它是一個數組)
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyAttributeView);
//a.getIndexCount()獲取屬性個數
for (int i = 0; i < a.getIndexCount(); i++) {
int index = a.getIndex(i);//所有屬性對應的id
switch (index) {
case R.styleable.MyAttributeView_my_age://年齡屬性id與之匹配
mAgeInt = a.getInt(i, 0);
break;
case R.styleable.MyAttributeView_my_name://姓名
mName = a.getString(i);
break;
case R.styleable.MyAttributeView_my_bg://背景圖片id
//拿到圖片,Drawable類型
Drawable drawable = a.getDrawable(i);
//我們需要的bitmap類型的圖片
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
mBitmap = bitmapDrawable.getBitmap();
break;
default:
break;
}
}
6_把取到的屬性值給給畫出來
@Override
protected void onDraw(Canvas canvas) {
canvas.drawText(mName + "-------------" + mAgeInt,50,50,mPaint);
canvas.drawBitmap(mBitmap,50,50,mPaint);
}
format 常用類型
reference 引用
color 顏色
boolean 布爾值
dimension 尺寸值
float 浮點值
integer 整型值
string 字符串
enum 枚舉
具體使用情況可以google~
有點幫助的話可以關注哈,有問題大家一起交流。也可以動手微信掃描下方二維碼查看更多安卓文章:
打開微信搜索公衆號 Android程序員開發指南 或者手機掃描下方二維碼 在公衆號閱讀更多Android文章。
微信公衆號圖片: