Androird自定义组合控件(一)

我将带给初学者自定义组合控件的快速学习方法,完成效果如图:
Androird自定义组合控件(一)_第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来保存用户配置信息。到此,我们就完成了自定义控件,相信你也想跃跃欲试了,多练练,多看看你就熟悉了。
由于在下才疏学浅,难免有错误之处,还望指正,谢谢!

你可能感兴趣的:(android)