先来看一张布局图片,

Android自定义小部件 android自定义控件入门与实战_android开发

这张图片的自动更新应用的item我们就可以设置成一个自定义控件,方便我们在往下重复使用。

定义自定义控件的步骤:

1.在layout文件夹下创建一个布局文件,改布局文件中包含了自定义组合控件中需要组合到一起的三个控件的布局。

2.定义一个自定义组合控件的类,用以对组合控件进行初始,设置等相关操作,方便调用者对我们的自定义控件进行一些操作。

3.在布局文件中进行使用,需要注意的地方:

3.1.引用自定义组合空间的布局文件中要设置自定义组合控件的命名空间,

3.2、全类名调用,(一会儿贴代码)

然后我们的自定义控件就可以显示在我们的布局页面上了,

在Activity中可以通过布局文件的id来获取该自定义组何控件,进而结合 自定义属性来设置自定义控件中每个控件的值。

第一步:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_margin="8sp"
    android:layout_height="wrap_content" >
    
	<TextView 
	    android:id="@+id/tv_set_title"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:textSize="20sp"
	    android:text="自动更新"
	    />
	<TextView 
	    android:id="@+id/tv_set_des"
	    android:layout_below="@id/tv_set_title"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:text="开启自动更新,仅wifi下自动更新"
	    android:focusable="false"
		android:clickable="false"
	    />

	<CheckBox
	    android:id="@+id/cb_status"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:gravity="center_vertical"
	    android:layout_alignBottom="@+id/tv_set_des"
	    android:layout_alignParentRight="true"
	    android:layout_marginRight="16dp"
	    android:focusable="false"
	    android:clickable="false"
	     />
	
	<View 
	    android:id="@+id/v_line"
	    android:layout_width="match_parent"
	    android:layout_height="0.5dp"
	    android:layout_marginTop="6sp"
	    android:layout_below="@id/cb_status"
	    android:background="#990000"
	    />

</RelativeLayout>


第二部:创建一个自定义组合控件类,继承一个布局(RelativeLayout  或者LeanerLayout等)

package com.hasee.mobilesafe.ui;

import com.hasee.mobilesafe.R;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class SettingView extends RelativeLayout {

	private TextView tv_set_title;
	private TextView tv_set_des;
	private CheckBox cb_status;
	private String des_on;
	private String des_off;

	public SettingView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}
 
	//这里使用了自定义的属性。
	public SettingView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
		//通过命名空间和属性的名称获取属性的值
		//namespace : 命名空间
		//name : 属性名称
		String namespace = "http://schemas.android.com/apk/res/com.hasee.mobilesafe";
		String title = attrs.getAttributeValue(namespace, "title");
		des_on = attrs.getAttributeValue(namespace, "des_on");
		des_off = attrs.getAttributeValue(namespace, "des_off");
		//给自定义组合控件的控件设置相应的值
				//初始化控件的值
		tv_set_title.setText(title);
		if(isChecked()){
			tv_set_des.setText(des_on);
		}else{
			tv_set_des.setText(des_off);
		}
		
	}
	
	public SettingView(Context context) {
		super(context);
		init();
	}
	public void init(){
		/**
		 * 初始化函数中:
		 * 1.填充布局文件
		 * 2.获取控件
		 */
		View.inflate(getContext(), R.layout.settingview, this);
		tv_set_title = (TextView) findViewById(R.id.tv_set_title);
		cb_status = (CheckBox) findViewById(R.id.cb_status);
		tv_set_des = (TextView) findViewById(R.id.tv_set_des);
	}
	
	/**
	 * 添加一些方法方便程序员调用的时候对该控件中的控件的值
	 */
	//设置标题信息
	public void setTitle(String title){
		tv_set_title.setText(title);
	}
	//设置描述信息
	public void setDes(String des){
		tv_set_des.setText(des);
		
	}
	//设置复选框状态   并且让复选框和TextView同步
	public void setChecked(boolean ischecked){
		cb_status.setChecked(ischecked);
		//让复选框和textView同步。
		if(ischecked){
			tv_set_des.setText(des_on);
		}else{
			tv_set_des.setText(des_off);
		}
	}
	//获取复选框状态
	public boolean isChecked(){
		return cb_status.isChecked();
	}
}

第三步:在需要使用自定义组合控件的布局文件中使用我们的组合控件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hasee="http://schemas.android.com/apk/res/com.hasee.mobile"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    
	<TextView 
	    android:id="@+id/tv_biaoti"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:text="设置中心"
	    android:textSize="39sp"
	    android:gravity="center_horizontal"
	    android:layout_marginTop="3dp"
	    android:background="#ffff02"
	    android:padding="5dp"
	    />
	<com.hasee.<span style="font-family: Arial, Helvetica, sans-serif;">mobilesafe</span>.ui.SettingView
	    android:id="@+id/sv_setting_update"
	    android:layout_below="@+id/tv_biaoti"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    hasee:title="自动更新"
	    hasee:des_on="开启自动更新"
	    hasee:des_off="关闭自动更新"
	    ></<span style="font-family: Arial, Helvetica, sans-serif;">com.hasee.</span><span style="font-family: Arial, Helvetica, sans-serif;">mobilesafe</span><span style="font-family: Arial, Helvetica, sans-serif;">.ui.SettingView</span>>
</RelativeLayout>

这里注意命名空间和全类名调用额。

接下来在代码中对我们的自定义组合控件进行设置操作。

package com.hasee.safemaster;

import com.hasee.safemaster.ui.SettingView;

import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

public class SettingActivity extends Activity implements OnClickListener {
	private SettingView sv_setting_update;
	private SharedPreferences sp;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.setting_layout);
		sv_setting_update = (SettingView) findViewById(R.id.sv_setting_update);
		sp = getSharedPreferences("config", MODE_PRIVATE);
		init();
		sv_setting_update.setOnClickListener(this);
	}

	private void init() {
		if(sp.getBoolean("update", true)){
			sv_setting_update.setChecked(true);
			
		}else{
			sv_setting_update.setChecked(false);
		}
	}

	@Override
	public void onClick(View v) {
		Editor edit = sp.edit();
		if(sv_setting_update.ischecked()){
			edit.putBoolean("update", false);
			sv_setting_update.setDes("关闭自动更新");
			sv_setting_update.setChecked(false);
		}else{
			edit.putBoolean("update", true);
			sv_setting_update.setDes("开启自动更新");
			sv_setting_update.setChecked(true);
		}
		edit.commit();
	}
}



这里我们使用到了自定义属性,说一下自定义属性的使用吧那就,

自定义属性的创建步骤:

1.在res-->>values文件夹下创建一个名为:attrs.xml的文件,设置自己需要定义的控件属性,这里使用的是组合控件,注意引入全类名。

2.在引用自定义组合控件的布局文件中使用自定义属性。

3.在自定义组合控件类中实现初始化、获取状态、设置值和状态等方法。

4.在代码中获取自定义组合控件(根据自定义控件的id)来对自定义的属性进行值或者状态的处理。

下面用代码来具体说明:

第一步:创建attrs.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="com.hasee.safemaster.ui.SettingView"><!--全类名-->
		        <attr name="title" format="string" /><!-- name:属性的名称,format:类型 -->
		        <attr name="des_on" format="string" />
		        <attr name="des_off" format="string" />
		    </declare-styleable>
</resources>

第二部:使用自定义属性

命名空间:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hasee="http://schemas.android.com/apk/res/com.hasee.safemaster"




<com.hasee.safemaster.ui.SettingView
	    android:id="@+id/sv_setting_update"
	    android:layout_below="@+id/tv_biaoti"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    hasee:title="自动更新"
	    hasee:des_on="开启自动更新"
	    hasee:des_off="关闭自动更新"
	    ></com.hasee.safemaster.ui.SettingView>

第三步和第四步:上面的代码中已经声明了在自定义控件类中对自定义属性的操作。不再贴代码

自定义控件使我们不必在每个布局文件中重复很多相似的代码。很实用。。。。