我将带给初学者自定义组合控件的快速学习方法,完成效果如图:
一、首先,完成这个的目的在于复用组件,加入另外一个新的组件也是同样的布局,仅仅只是显示的文字不同,那么他就实现了他的人生价值。要完成这个效果图,首先分析这个布局,采用相对布局是最合适的。对于布局分析,不再细说,不会的可以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来保存用户配置信息。到此,我们就完成了自定义控件,相信你也想跃跃欲试了,多练练,多看看你就熟悉了。
由于在下才疏学浅,难免有错误之处,还望指正,谢谢!