自定义组合控件
一、步骤:
- 根据相应的布局文件类型来自定义一个类(
SettingItemView )继承与对应的布局类型的类(如:
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="60dip" >
<TextView
android:layout_marginTop="5dip"
android:layout_marginLeft="10dip"
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置自动更新"
android:textSize="20sp" />
<TextView
android:layout_marginTop="5dip"
android:layout_marginLeft="10dip"
android:id="@+id/tv_desc"
android:textColor="#55000000"
android:layout_below="@id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自动更新已经开启"
android:textSize="16sp"
/>
<CheckBox
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:id="@+id/cb_isupdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true" />
<View
android:layout_width="match_parent"
android:layout_height="0.2dip"
android:background="#55000000"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
三、自定义一个类 (SettingItemView)
<?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="60dip" >
<TextView
android:layout_marginTop="5dip"
android:layout_marginLeft="10dip"
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置自动更新"
android:textSize="20sp" />
<TextView
android:layout_marginTop="5dip"
android:layout_marginLeft="10dip"
android:id="@+id/tv_desc"
android:textColor="#55000000"
android:layout_below="@id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自动更新已经开启"
android:textSize="16sp"
/>
<CheckBox
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:id="@+id/cb_isupdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true" />
<View
android:layout_width="match_parent"
android:layout_height="0.2dip"
android:background="#55000000"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
三、自定义一个类 (SettingItemView)
该类所要继承的类是根据该布局文件的布局文件类型来定的,例如自定义的控件所用的布局为相对布局,该类就继承与RelativeLayout
package com.app.mobilesafe.ui;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.itheima.mobilesafe.R;
public class SettingItemView extends RelativeLayout{
private CheckBox cb_isupdate;
private TextView tv_desc;
private TextView tv_title;
private View view;
private String update_off;
private String update_on;
private String title;
/**
* 在布局文件中使用这个控件时,如果指定了样式,系统初始化布局文件中的这个控件时,调用这个方法
* @param context
*/
public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
/**
* 初始化布局文件中的这个控件时,系统默认调用这个方法 (该构造方法中有一个参数attrs,安卓底层利用反射将xml文件中的属性存放在AttributeSet 对象中)
* @param context
*/
public SettingItemView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
//如果属性是是系统默认的namespace就写为null; - String id=attrs.getAttributeValue(null,"id")+"";
- //如果属性是自定义的namespace就为写在相应xml文件中namespace
update_off = attrs.getAttributeValue("http://schemas.android.com/apk/com.itheima.mobilesafe", "update_off")+"";
update_on = attrs.getAttributeValue("http://schemas.android.com/apk/com.itheima.mobilesafe", "update_on")+"";
title = attrs.getAttributeValue("http://schemas.android.com/apk/com.itheima.mobilesafe", "title")+"";
tv_title.setText(title);
}
/**
* 在代码new这个对象时使用这个方法
* @param context
*/
public SettingItemView(Context context) {
super(context);
initView(context);
// TODO Auto-generated constructor stub
}
public void initView(Context context){
view = View.inflate(context, R.layout.settings_item_view, this);
tv_title = (TextView) view.findViewById(R.id.tv_title);
tv_desc = (TextView) view.findViewById(R.id.tv_desc);
cb_isupdate = (CheckBox) view.findViewById(R.id.cb_isupdate);
}
public boolean isChecked(){
return cb_isupdate.isChecked();
}
public void setChecked(boolean checked) {
if(checked){
tv_desc.setText(update_on);
}else{
tv_desc.setText(update_off);
}
cb_isupdate.setChecked(checked);
}
}
package com.app.mobilesafe.ui;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.itheima.mobilesafe.R;
public class SettingItemView extends RelativeLayout{
private CheckBox cb_isupdate;
private TextView tv_desc;
private TextView tv_title;
private View view;
private String update_off;
private String update_on;
private String title;
/**
* 在布局文件中使用这个控件时,如果指定了样式,系统初始化布局文件中的这个控件时,调用这个方法
* @param context
*/
public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
/**
* 初始化布局文件中的这个控件时,系统默认调用这个方法 (该构造方法中有一个参数attrs,安卓底层利用反射将xml文件中的属性存放在AttributeSet 对象中)
* @param context
*/
public SettingItemView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
//如果属性是是系统默认的namespace就写为null;
- String id=attrs.getAttributeValue(null,"id")+"";
- //如果属性是自定义的namespace就为写在相应xml文件中namespace
update_off = attrs.getAttributeValue("http://schemas.android.com/apk/com.itheima.mobilesafe", "update_off")+"";
update_on = attrs.getAttributeValue("http://schemas.android.com/apk/com.itheima.mobilesafe", "update_on")+"";
title = attrs.getAttributeValue("http://schemas.android.com/apk/com.itheima.mobilesafe", "title")+"";
tv_title.setText(title);
}
/**
* 在代码new这个对象时使用这个方法
* @param context
*/
public SettingItemView(Context context) {
super(context);
initView(context);
// TODO Auto-generated constructor stub
}
public void initView(Context context){
view = View.inflate(context, R.layout.settings_item_view, this);
tv_title = (TextView) view.findViewById(R.id.tv_title);
tv_desc = (TextView) view.findViewById(R.id.tv_desc);
cb_isupdate = (CheckBox) view.findViewById(R.id.cb_isupdate);
}
public boolean isChecked(){
return cb_isupdate.isChecked();
}
public void setChecked(boolean checked) {
if(checked){
tv_desc.setText(update_on);
}else{
tv_desc.setText(update_off);
}
cb_isupdate.setChecked(checked);
}
}
四、在values文件夹下创建一个attrs.xml文件
将要自定义的属性写在该xml文件中(注:谷歌官方推荐自定义的属性要在这里声明一下,但是在实际中不声明而是在该组合控件的java文件中声明也可以使用)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SettingItemView"> 注:这里写的是该组合控件的类的名字
<attr name="update_off" format="reference" />
<attr name="update_on" format="reference"/>
<attr name="title" format="reference"/>
</declare-styleable>
</resources>
五、自定义属性
需要在SettingItemView.java的初始化时声明
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:safe="http://schemas.android.com/apk/com.app.safe"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:text="设置中心"
android:textSize="20sp"
android:background="#ff0000"
/>
<com.app.ui.SettingItemView
android:id="@+id/my_setting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
safe:title="设置自动更新"
safe:update_off="自动更新已经关闭"
safe:update_on="自动更新已经开启"
/>
<com.app.ui.SettingItemView
android:id="@+id/app_lock_setting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
safe:title="设置程序锁"
safe:update_on="程序锁已经开启"
safe:update_off="程序锁已经关闭"
/>
</LinearLayout>