在开发应用程序的时候,很多时候会使用到几个重复的控件,例如Android手机的设置界面里面的位置服务里面的每一栏都是组合控件,也就是说多个控件组成一个整体,如下图所示:
红色方框里面的是由两个TextView和一个CheckBox组合而成的一个组合控件,要是能把这两个控件组合成一个控件在开发过程中就有有很大的方便,
在主布局文件中activity_mian:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="80dp" >
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20sp"
android:text="GOOGLE的位置服务"/>
<TextView
android:id="@+id/tv_desc"
android:layout_below="@id/tv_title"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:textColor="#88000000"
android:textSize="18sp"
android:text="允许应用程序使用来自WALN或移动网络的数据确定您的大致位置"/>
<CheckBox
android:id="@+id/cb_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"/>
<View
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:layout_below="@id/tv_desc"
android:background="#000000"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
</RelativeLayout>
</RelativeLayout>
在这里实现这一个单元的控件,但是还有两个单元的控件布局类似,如果还是按照上面的代码往下写,就会造成代码的重复,而且不好看,所以这里就会使用到一个组合控件,很方面的解决这个问题,首先把重复的代码抽取出来
<?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="80dp" >
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20sp"
android:text="GOOGLE的位置服务"/>
<TextView
android:id="@+id/tv_desc"
android:layout_below="@id/tv_title"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:textColor="#88000000"
android:textSize="18sp"
android:text="允许应用程序使用来自WALN或移动网络的数据确定您的大致位置"/>
<CheckBox
android:id="@+id/cb_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"/>
<View
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:layout_below="@id/tv_desc"
android:background="#000000"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
</RelativeLayout>
创建一个自定义的类ItemView.java,该方法继承了RelativeLayout,实现了一下三个方法
public ItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
public ItemView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public ItemView(Context context) {
super(context);
initView(context);
}
在调用这三个方法时都会对调用initView(context)方法对item_view.xml中的三个控件进行初始化。
<span style="white-space:pre"> </span>// 把一个布局文件----》一个View,并且加载在SettingItemView中
private void initView(Context context) {
View view = View.inflate(getContext(), R.layout.item_view, ItemView.this);
cb_status = (CheckBox) view.findViewById(R.id.cb_status);
tv_desc = (TextView) view.findViewById(R.id.tv_desc);
tv_title = (TextView) view.findViewById(R.id.tv_title);
}
要重复利用组合控件里面的三个子控件,就还要实现一下几个方法,分别是isChecked()判断CheckBox是否选中,setChecked(boolean checked)设置
CheckBox的状态,setDesc(String text)修改描述信息,setTitle(String text)修改标题等。
/*
* 组合控件是否有焦点
* */
public boolean isChecked(){
return cb_status.isChecked();
}
/*
* 设置组合控件的状态
* */
public void setChecked(boolean checked){
cb_status.setChecked(checked);
}
/*
* 组合控件更改文字
* */
public void setDesc(String text){
tv_desc.setText(text);
}
/*
* 组合控件更改标题
* */
public void setTitle(String text){
tv_title.setText(text);
}
然后要使用这个组合控件的话就可以在activity_main.xml布局中直接调用自定义控件了。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<cn.edu.cqu.zhkj.ItemView
android:id="@+id/iv_google"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<cn.edu.cqu.zhkj.ItemView
android:id="@+id/iv_gps"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<cn.edu.cqu.zhkj.ItemView
android:id="@+id/iv_es_gps"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
在主布局文件中添加三个自定义的控件,然后在程序中进行设置。
package cn.edu.cqu.zhkj;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity{
private ItemView iv_google;
private ItemView iv_gps;
private ItemView iv_es_gps;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_google = (ItemView) findViewById(R.id.iv_google);
iv_gps = (ItemView) findViewById(R.id.iv_gps);
iv_es_gps = (ItemView) findViewById(R.id.iv_es_gps);
iv_gps.setTitle("GPS卫星");
iv_gps.setDesc("允许应用程序使用GPS对您进行定位");
iv_es_gps.setTitle("使用增强型GPS");
iv_es_gps.setDesc("可以使用服务器辅助GPS(取消选中可以降低网络使用率)");
iv_google.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 判断是否选中
if (iv_google.isChecked()) {
iv_google.setChecked(false);
}else {
iv_google.setChecked(true);
}
}
});
iv_gps.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 判断是否选中
if (iv_gps.isChecked()) {
iv_gps.setChecked(false);
}else {
iv_gps.setChecked(true);
}
}
});
iv_es_gps.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 判断是否选中
if (iv_es_gps.isChecked()) {
iv_es_gps.setChecked(false);
}else {
iv_es_gps.setChecked(true);
}
}
});
}
}
这样就实现了组合控件的重复使用。
源码下载:组合控件