Android自定義組合控件

目標:實現textview和ImageButton組合,可以通過Xml設置自定義控件的屬性。
[b][size=x-large]1.控件佈局:以Linearlayout爲根佈局,一個TextView,一個ImageButton。[/size][/b]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:gravity="center_vertical">
<TextView android:layout_height="wrap_content" android:id="@+id/text1"
android:layout_width="wrap_content"></TextView>
<ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/btn1"></ImageButton>
</LinearLayout>

[b][size=x-large]2.自定義控件代碼,從LinearLayout繼承:[/size][/b]
public class ImageBtnWithText extends LinearLayout {

public ImageBtnWithText(Context context) {
this(context, null);
}

public ImageBtnWithText(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.imagebtn_with_text, this, true);
}
}

在構造函數中將Xml中定義的佈局解析出來。
PS:有時執行此句代碼時eclipse會輸出找不到資源,而無法預覽自定義控件。經試驗確定是新增的佈局沒有生成資源,但是clean project重新生成也不行,最後重啓eclipse解決。
[b][size=x-large]3.在主界面佈局xml中使用自定義控件:[/size][/b]
<com.demo.widget2.ImageBtnWithText
android:id="@+id/widget"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />

即使用完整的自定義控件類路徑:com.demo.widget2.ImageBtnWithText定義一個元素。
運行可以看到控件已經能夠被加載到界面上。
[b][size=x-large]4.給按鈕設置圖片和文本[/size][/b]
如果圖片是固定不變的,那麼直接在控件佈局中設置ImageButton的src屬性即可。
[b][size=large]4.1通過Java代碼設置,在控件代碼中提供函數接口:[/size][/b]
public void setButtonImageResource(int resId) {
mBtn.setImageResource(resId);
}

public void setTextViewText(String text) {
mTv.setText(text);
}

然後再在主界面的onCreate()通過函數調用設置即可。
[b][size=large]4.2通過Xml設置屬性[/size][/b]
[b]4.2.1首先定義Xml可以設置的屬性集合,在values下創建attrs.xml,文件名可隨意,一般都叫attrs.xml[/b]
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ImageBtnWithText">
<attr name="android:text"/>
<attr name="android:src"/>
</declare-styleable>
</resources

屬性集合名字:ImageBtnWithText,自己可根據實際來定義;
集合中包含的屬性列表,每行一個屬性。
[b]4.2.2修改自定義控件實現代碼,以獲取xml中定義的屬性[/b]
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ImageBtnWithText);
CharSequence text = a.getText(R.styleable.ImageBtnWithText_android_text);
if(text != null) mTv.setText(text);
Drawable drawable = a.getDrawable(R.styleable.ImageBtnWithText_android_src);
if(drawable != null) mBtn.setImageDrawable(drawable);
a.recycle()

首先通過context.obtainStyledAttributes獲得所有屬性數組;
然後通過TypedArray類的getXXXX()系列接口獲得相應的值。
[b]4.2.3在主界面佈局中設置自定義控件的屬[/b]
android:text="ABC" android:src="@drawable/icon
[b][size=large]4.3自定義名稱屬性:[/size][/b]
在4.2中使用的屬性名是android系統命名空間的,都以android開頭,比如android:text等。
實際開發中會自定義一些屬性名,這些屬性名仍然定義在4.2.1提到的attrs.xml中:
[b]4.3.1定義屬性名[/b]
<attr name="appendText" format="string"/>

和直接使用系統的attr不同的是要增加一個format屬性,說明此屬性是什麼格式的。format可選項可參見注1
[b]4.3.2使用自定義屬性[/b]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myspace="http://schemas.android.com/apk/res/com.demo.customwidget"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.demo.widget2.ImageBtnWithText
android:text="ABC" android:src="@drawable/icon" android:id="@+id/widget"
android:layout_width="fill_parent" android:layout_gravity="center"
android:layout_height="fill_parent" myspace:appendText="123456">
</com.demo.widget2.ImageBtnWithText>
</LinearLayout>

直接在主佈局文件中使用此屬性appendText="abc"是不會設置生效的,而是要在主佈局xml中定義一個xml命名空間:
xmlns:myspace="http://schemas.android.com/apk/res/com.demo.customwidget"
命名空間的名字可以自己隨便定義,此處爲myspace,即xmlns:myspace;
後面的地址則有限制,其開始必須爲:"http://schemas.android.com/apk/res/",後面則是包名com.demo.customwidget,
此處的包名與AndroidManifest.xml中<manifest>節點的屬性package="com.demo.customwidget"一致,不是自定義控件Java代碼所在的包,當然簡單的程序自定義控件Java代碼也一般在此包內。

注1:
注1:format可選項
"reference" //引用
"color" //顏色
"boolean" //布爾值
"dimension" //尺寸值
"float" //浮點值
"integer" //整型值
"string" //字符串
"fraction" //百分數,比如200%
枚舉值,格式如下:
<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
xml中使用時:
android:orientation = "vertical"

標誌位,位或運算,格式如下:
<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>
xml中使用時:
android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden">


另外屬性定義時可以指定多種類型值,比如:
<attr name = "background" format = "reference|color" />
xml中使用時:
android:background = "@drawable/圖片ID|#00FF00"
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章