自定义组合控件实现

安辉 2014-01-07

     在android中有时我们需要根据需求自定义控件,自定义组合控件是较简单的一种,下面我们来实现一下设置里面的常用效果:


自定义组合控件实现
 

    首先,自定义组合空间主要分为以下几个步骤:

    1,编写自定义控件的布局文件.

    2,在values目录下,添加自定义控件相对应的,属性资源文件attrs.xml.用来自定义一些属性.

    3,创建自定义控件的View对象继承ViewGroup的一个子类就可以了(一般选择RelativeLayout或者LinearLayout),重写参数列表为(Context context, AttributeSet attrs)的构造方法.

    4,在构造方法中通过context上下文的obtainStyledAttributes方法找到自定义的属性数组TypedArray(获取结束后记得调用TypedArray.recycle()方法,释放资源.)

    5,通过引用自定义组合控件的完整类名就可以在其他布局文件中使用自定义组合控件了,

    6,添加自定义组合控件的命名空间声明,就可以在xml布局文件中直接设置第2步中自定义的属性了.

       源码下载

下面一步一步来试试看:

    0,创建一个android工程.

    1,编写自定义控件的布局文件.

    ui_setting.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="60dp" >

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="5dp"
            android:paddingTop="5dp"
            android:text="设置的说明"
            android:textSize="26sp" />

        <TextView
            android:id="@+id/tv_desc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/tv_title"
            android:layout_marginLeft="10dp"
            android:text="状态"
            android:textColor="@android:color/darker_gray"
            android:textSize="14sp" />
    </RelativeLayout>

    <CheckBox
        android:id="@+id/cb_status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="5dp"
        android:clickable="false"
        android:focusable="false" />

</RelativeLayout>

    2.在values目录下,添加自定义控件相对应的属性资源文件attrs.xml.用来自定义一些属性.

     attrs.xml:

<resources>

    <declare-styleable name="MyView">
        <attr name="title" format="string" />
        <attr name="desc_on" format="string" />
        <attr name="desc_off" format="string" />
    </declare-styleable>

</resources>

    3,创建自定义控件的View对象继承ViewGroup的一个子类就可以了(一般选择RelativeLayout或者LinearLayout),重写参数列表为(Context context, AttributeSet attrs)的构造方法.

   4,在构造方法中通过context上下文的obtainStyledAttributes方法找到自定义的属性数组TypedArray(获取结束后记得调用TypedArray.recycle()方法,释放资源.)

public class MyView extends LinearLayout {

	private CheckBox cb_status;
	private TextView tv_desc;
	private TextView tv_title;
	private String title;
	private String desc_on;
	private String desc_off;
	
	private void init(Context context) {
		//为当前view对象设置布局
		View.inflate(context, R.layout.ui_setting , this);
		
		cb_status = (CheckBox) findViewById(R.id.cb_status);
		tv_desc = (TextView) findViewById(R.id.tv_desc);
		tv_title = (TextView) findViewById(R.id.tv_title);
	}
	//复写父类的构造方法
	public MyView(Context context, AttributeSet attrs) {
		super(context, attrs);
		//初始化view对象
		init(context);
		// 通过上下文context获取自定义属性
		TypedArray typeArr = context.obtainStyledAttributes(attrs,R.styleable.MyView);
		// 获取在xml文件中,自定义属性的值
		title = typeArr.getString(R.styleable.MyView_title);
		desc_on = typeArr.getString(R.styleable.MyView_desc_on);
		desc_off = typeArr.getString(R.styleable.MyView_desc_off);
		//释放资源
		typeArr.recycle();
		// 设置title
		setTitle(title);
		// 设置选中状态
		if(isChecked()){
			setDesc(desc_on);
		}else{
			setDesc(desc_off);
		}
		// 添加点击事件
		this.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				setChecked(!isChecked());
			}
		});
	}
	
	public boolean isChecked() {
		return cb_status.isChecked();
	}

	public void setChecked(boolean checked){
		this.cb_status.setChecked(checked);
		if(checked){
			setDesc(desc_on);
		}else{
			setDesc(desc_off);
		}
	}
	public void setTitle(String title){
		tv_title.setText(title);
	}
	public void setDesc(String desc){
		this.tv_desc.setText(desc);
	}
}

    5,通过引用自定义组合控件的完整类名就可以在其他布局文件中使用自定义组合控件,

    6,添加自定义组合控件的命名空间声明,就可以在xml布局文件中直接设置第2步中自定义的属性.

    自定义控件的命名空间一般这样定义:

    xmlns : "别名" = "http://schemas.android.com/apk/res/" + "应用程序包名"

  activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myui="http://schemas.android.com/apk/res/com.***.myview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
<!-- 引用自定义控件的完整类名 -->
    <com.***.myview.MyView
        android:id="@+id/mview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        myui:desc_off="关闭"
        myui:desc_on="开启"
        myui:title="自定义的组合控件01" >
    </com.***.myview.MyView>

</LinearLayout>

    

   2014年1月7日 17:50:13 笔记---end

相关推荐