我將帶給初學者自定義組合控件的快速學習方法,完成效果如圖:
圖1 自定義組合控件效果圖
一、首先,完成這個的目的在於複用組件,加入另外一個新的組件也是同樣的佈局,僅僅只是顯示的文字不同,那麼他就實現了他的人生價值。要完成這個效果圖,首先分析這個佈局,採用相對佈局是最合適的。對於佈局分析,不再細說,不會的可以call我。下面直接給出這個xml佈局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/tv_setting_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="22sp"/>
<TextView
android:id="@+id/tv_setting_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_below="@id/tv_setting_title"
android:textColor="#88000000"
android:textSize="18sp"/>
<CheckBox
android:id="@+id/cb_state"
android:focusable="false"
android:clickable="false"
android:layout_marginRight="10dp"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"/>
<View
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:layout_alignParentBottom="true"
android:background="#000000"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
</RelativeLayout>
二、我們要新建一個類,繼承相對佈局管理器,也就是RelativeLayout,然後完成裏面的三個方法,分別是:
(如果找不到這三個方法的,可以copy我的,也可以快速修復錯誤,讓eclipse生成方法,它生成的可能與我的有所不同)
public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public SettingItemView(Context context, AttributeSet attrs) {
super(context, attrs);
}
//構造方法
public SettingItemView(Context context) {
super(context);
}
然後我們自己在定義一個自己的方法,用來加載佈局文件,其方法如下:
private void inView(Context context) {
View.inflate(context, R.layout.setting_item_view,this);
this.cb_state = (CheckBox)this.findViewById(R.id.cb_state);
this.tv_setting_tip = (TextView)this.findViewById(R.id.tv_setting_tip);
this.tv_setting_title = (TextView)this.findViewById(R.id.tv_setting_title);
}
在這個方法中用View.infalte來加載我們剛纔寫的佈局文件,將佈局文件裏的兩個TextView和CheckBox的ID取得,作爲本類的成員變量。
最後在上面的三個方法中調用這個方法。
三、自定義控件的屬性。
在在res/values/下建立attrs.xml文件,名字要相同,不能變,添加以下屬性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TextView">
<attr name="titleTip" format="string"/>
<attr name="desc_on" format="string"/>
<attr name="desc_off" format="string"/>
</declare-styleable>
</resources>
四、取得屬性值
在上述方法中取得佈局文件裏的值,將他們填充到我們定義的組合控件中,很需要注意的是,取得屬性值的路徑“http://schemas.android.com/apk/res/”是不變的,而後面的“com.mess.client”一定要是你應用程序清單文件裏的包名,(兩條線包圍部分) 如果不是這個包名,eclipse會報錯,程序也無法運行。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
/**************************************/
package="com.mess.client"
/**************************************/
android:versionCode="2"
android:versionName="2.0" />
public SettingItemView(Context context, AttributeSet attrs) {
super(context, attrs);
inView(context);
String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.mess.client", "titleTip");
desc_on = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.mess.client", "desc_on");
desc_off = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.mess.client", "desc_off");
//將取得的文本內容填充到TextView控件上
tv_setting_title.setText(title);
tv_setting_tip.setText(desc_off);
}
五、響應組合控件的事件
我們將要完成的功能是,當用戶點擊了這個控件時,CheckBox如果爲true,我們就要將第二個TextView進行開啓和關閉的顯示提示。添加一下三個方法,實現事件響應。
/*
* 校驗是否選中
*/
public boolean isChecked(){
return this.cb_state.isChecked();
}
/*
* 設置組合控件的狀態
*/
public void setChecked(boolean checked){
if(checked){
tv_setting_tip.setText(desc_on);
}else{
tv_setting_tip.setText(desc_off);
}
this.cb_state.setChecked(checked);
}
/*
* 設置組合控件的描述信息
*/
public void setTextViewTip(String text){
tv_setting_tip.setText(text);
}
六、使用組合控件
完成上面的麻煩事後,接下來就如魚得水了。根據代碼的中的提示添加代碼。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
/*添加此段代碼,messclient是根據你的喜好任意命名的,"com.mess.client"則是你應用程序清單裏的程序包名,同上文提到的一樣,不能搞錯。
*/
xmlns:messclient="http://schemas.android.com/apk/res/com.mess.client"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mess.client.ui.SettingItemView
/*
而此處,則用你自定義的名稱添加屬性,屬性名稱是你在res/values/attrs.xml裏定義的,也不能錯。
*/
messclient:titleTip="設置自動更新"
messclient:desc_on="自動升級已開啓"
messclient:desc_off="自動升級已關閉"
android:id="@+id/siv_auto_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
七、監聽事件
在你引入這個佈局的activity中通過id找到這個控件,現在這個控件的類型則是我們自定義的類名。監聽代買同基本組件監聽一樣了,直接來真的。
this.siv_update.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Editor editor = sp.edit();
// TODO Auto-generated method stub
if (siv_update.isChecked()) {
// 已經打開自動升級
siv_update.setChecked(false);
// siv_update.setTextViewTip("自動升級已關閉");
editor.putBoolean("update", false);
} else {
siv_update.setChecked(true);
// siv_update.setTextViewTip("自動升級已開啓");
editor.putBoolean("update", true);
}
editor.commit();// 提交要保存的數據
}
});
在這裏,你們還可以用SharedPreferences來保存用戶配置信息。到此,我們就完成了自定義控件,相信你也想躍躍欲試了,多練練,多看看你就熟悉了。
由於在下才疏學淺,難免有錯誤之處,還望指正,謝謝!