自定义组合控件
1. 自定义一个View, 继承ViewGroup,比如RelativeLayout,此文中是SettingItemView
2. 编写组合控件的布局文件,在自定义的View中加载
            // 将自定义好的布局文件设置给当前的SettingItemView
        View.inflate(getContext(), R.layout.view_setting_item, this);
3. 自定义属性

删除代码中对文本的动态设置,改为在布局文件中设置

在布局文件中增加新的命名空间

创建attrs.xml,定义相关属性

读取自定义的值,更新相关内容

activity_setting.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mobilesafe
="http://schemas.android.com/apk/res/com.mxn.mobilesafe"//自定义命名空间。。。在布局文件中增加新的命名空间
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <TextView style="@style/TitleStyle"
android:text="设置中心" /> <com.mxn.mobilesafe.view.SettingItemView
android:id="@+id/siv_update"
android:layout_width="match_parent"
android:layout_height="wrap_content" //自定义属性,不用android默认的属性
//从命名空间中找
mobilesafe:title
="自动更新设置"
mobilesafe:desc_on
="自动更新已开启"
mobilesafe:desc_off
="自动更新已关闭" >
</com.mxn.mobilesafe.view.SettingItemView> <com.mxn.mobilesafe.view.SettingItemView
android:id="@+id/siv_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
mobilesafe:title="归属地显示设置"
mobilesafe:desc_on="归属地显示已开启"
mobilesafe:desc_off="归属地显示已关闭" >
</com.mxn.mobilesafe.view.SettingItemView> <com.mxn.mobilesafe.view.SettingClickView
android:id="@+id/scv_address_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</com.mxn.mobilesafe.view.SettingClickView> <com.mxn.mobilesafe.view.SettingItemView
android:id="@+id/siv_watchdog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
mobilesafe:title="看门狗设置"
mobilesafe:desc_on="看门狗已开启"
mobilesafe:desc_off="看门狗已关闭" >
</com.mxn.mobilesafe.view.SettingItemView> </LinearLayout>
自定义属性 : attrs.xml。。创建attrs.xml,定义相关属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SettingItemView">
<attr name="title" format="string"></attr>
<attr name="desc_on" format="string"></attr>
<attr name="desc_off" format="string"></attr> </declare-styleable> </resources>
 
SettingItemView.java
/*
* 设置中心的自定义控件,自定义View
*/
public class SettingItemView extends RelativeLayout {
TextView tvTitle;
TextView tvDesc;
CheckBox cbStatus;
private String mtitle;
private String mdescon;
private String mdescoff;
String namespace = "http://schemas.android.com/apk/res/com.mxn.mobilesafe";//命名空间 public SettingItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
// TODO Auto-generated constructor stub
initView();
} public SettingItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub

initView();

// int attributeCount = attrs.getAttributeCount();
// for(int i=0;i<attributeCount;i++){
// String attrsname = attrs.getAttributeName(i);
// String attrvalue = attrs.getAttributeValue(i);
// System.out.println(attrsname+"="+attrvalue);
//
// } } public SettingItemView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
// 读取自定义的值,更新相关内容
//根据属性名称获取属性的值
mtitle = attrs.getAttributeValue(namespace , "title");
mdescon = attrs.getAttributeValue(namespace , "desc_on");
mdescoff = attrs.getAttributeValue(namespace , "desc_off"
);
initView();

} public SettingItemView(Context context) {
super(context);
// TODO Auto-generated constructor stub
initView();
} // 初始化布局
private void initView() {
// 把自定义好的布局设置给当前的SettingItemView
View.inflate(getContext(), R.layout.view_setting_item, this);// this表示把view_setting_item布局塞给RelativeLayout
tvTitle = (TextView) findViewById(R.id.tv_title);
tvDesc = (TextView) findViewById(R.id.tv_desc);
cbStatus = (CheckBox) findViewById(R.id.cb_status); setTitle(mtitle); } public void setTitle(String title) {
tvTitle.setText(title);
} public void setDesc(String desc) {
tvDesc.setText(desc);
} // 判断当前的勾选状态并返回
public boolean isChecked() {
return cbStatus.isChecked();
} public void setChecked(boolean check){
cbStatus.setChecked(check);
//根据选择的状态更新文本描述
if(check){
setDesc(mdescon);
}else
{
setDesc(mdescoff);
}

}
}
view_setting_item.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="80dp"
android:padding="10dp"> <TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:textColor="@color/black"
android:textSize="20sp"/>
<TextView
android:id="@+id/tv_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:textColor="#a000"
android:layout_below="@id/tv_title"
android:textSize="15sp"/>
<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:clickable
="false"//表示不能点击
android:focusable
="false"//不能获取焦点
android:focusableInTouchMode
="false"
/>
<View
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:background="#a000"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
SettingClickView.java
/*
* 设置中心的自定义控件,自定义View
*/
public class SettingClickView extends RelativeLayout {
private TextView tvTitle;
private TextView tvDesc; public SettingClickView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
} public SettingClickView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
} public SettingClickView(Context context) {
super(context);
initView();
} /**
* 初始化布局
*/
private void initView() {
// 将自定义好的布局文件设置给当前的SettingClickView
View.inflate(getContext(), R.layout.view_setting_click, this);
tvTitle = (TextView) findViewById(R.id.tv_title);
tvDesc = (TextView) findViewById(R.id.tv_desc);
} public void setTitle(String title) {
tvTitle.setText(title);
} public void setDesc(String desc) {
tvDesc.setText(desc);
} }
view_setting_click.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="80dp"
android:padding="10dp"> <TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:textColor="@color/black"
android:textSize="20sp"/>
<TextView
android:id="@+id/tv_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:textColor="#a000"
android:layout_below="@id/tv_title"
android:textSize="15sp"/>
<ImageView
android:src="@drawable/jiantou1_pressed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:id="@+id/iv_jt"
/>
<View
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:background="#a000"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>

运行界面:

SettingActivity.java

/**
* 设置中心
*
* @author mxn
*
*/
public class SettingActivity extends Activity { private SettingItemView sivUpdate;// 设置自动更新
private SettingItemView sivAddress;// 设置归属地
private SettingClickView scvAddressStyle;// 修改风格
private SettingClickView scvAddressLocation;// 修改归属地位置
private SharedPreferences mPref; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting); mPref = getSharedPreferences("config", MODE_PRIVATE);
//MODE_PRIVATE访问权限
initUpdateView();
initAddressView();
initAddressStyle();
} /**
* 初始化自动更新开关
*/
private void initUpdateView() {
sivUpdate = (SettingItemView) findViewById(R.id.siv_update);
// sivUpdate.setTitle("自动更新设置");
//默认设置的开启,用户进入之后
boolean autoUpdate = mPref.getBoolean("auto_update", true); if (autoUpdate) {
// sivUpdate.setDesc("自动更新已开启");
sivUpdate.setChecked(true);
} else {
// sivUpdate.setDesc("自动更新已关闭");
sivUpdate.setChecked(false);
} sivUpdate.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// 判断当前的勾选状态
if (sivUpdate.isChecked()) {
// 设置不勾选
sivUpdate.setChecked(false);
// sivUpdate.setDesc("自动更新已关闭");
// 更新sp
mPref.edit().putBoolean("auto_update", false).commit();
} else {
sivUpdate.setChecked(true);
// sivUpdate.setDesc("自动更新已开启");
// 更新sp
mPref.edit().putBoolean("auto_update", true).commit();
}
}
});
} /**
* 初始化归属地开关显示
*/
private void initAddressView() {
sivAddress = (SettingItemView) findViewById(R.id.siv_address); // 根据归属地服务是否运行来更新checkbox
boolean serviceRunning = ServiceStatusUtils.isServiceRunning(this,
"com.itheima52.mobilesafe.service.AddressService"); if (serviceRunning) {
sivAddress.setChecked(true);
} else {
sivAddress.setChecked(false);
} sivAddress.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
if (sivAddress.isChecked()) {
sivAddress.setChecked(false);
stopService(new Intent(SettingActivity.this,
AddressService.class));// 停止归属地服务
} else {
sivAddress.setChecked(true);
startService(new Intent(SettingActivity.this,
AddressService.class));// 开启归属地服务
}
}
});
} final String[] items = new String[] { "半透明", "活力橙", "卫士蓝", "金属灰", "苹果绿" }; /**
* 修改归属地提示框显示风格
*/
private void initAddressStyle() {
scvAddressStyle = (SettingClickView) findViewById(R.id.scv_address_style); scvAddressStyle.setTitle("归属地提示框风格"); int style = mPref.getInt("address_style", 0);// 读取保存的style
scvAddressStyle.setDesc(items[style]); scvAddressStyle.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
showSingleChooseDailog();
}
});
} /**
* 弹出选择风格的单选框
*/
protected void showSingleChooseDailog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// builder.setIcon(R.drawable.ic_launcher);
builder.setTitle("归属地提示框风格"); int style = mPref.getInt("address_style", 0);// 读取保存的style builder.setSingleChoiceItems(items, style,
new DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialog, int which) {
mPref.edit().putInt("address_style", which).commit();// 保存选择的风格
dialog.dismiss();// 让dialog消失 scvAddressStyle.setDesc(items[which]);// 更新组合控件的描述信息
}
}); builder.setNegativeButton("取消", null);
builder.show();
} }

最新文章

  1. 学习了一下javascript的模块化编程
  2. WPF SDK研究 之 AppModel
  3. The ServiceClass object does not implement the required method in the following form: OMElement sayHello(OMElement e)
  4. 3.PHP内核探索:一次请求生命周期
  5. g++安装 Gnome/Gtk+开发库 的 环境安装(安装widgets的必要条件)
  6. 0_Linux_虚拟机安装
  7. 数论(容斥原理)hdu-4509-The Boss on Mars
  8. 转:selenium webdriver 执行javascript代码
  9. 【实验吧】逆向rev50
  10. 深夜学算法之SkipList:让链表飞
  11. 【Python3爬虫】Scrapy入门教程
  12. fetch跨域浏览器请求头待研究
  13. SHELL脚本--shell数组基础
  14. rabbitmq安装及基本操作(含集群配置)
  15. 微软职位内部推荐-SW Engineer II for Embedded System
  16. JAVA中如何将一个json形式的字符串转为json对象
  17. u3d DontDestroyOnLoad多场景问题
  18. 使用postman测试接口时需要先登录怎么办
  19. 【读书笔记::深入理解linux内核】内存寻址【转】
  20. IC设计笔试面试小问题总结(随时更新)-IC设计笔记(三)

热门文章

  1. chromium浏览器开发系列第五篇:Debugging with WinDBG
  2. CF-851B
  3. 《Java多线程编程核心技术》读后感(九)
  4. web前端之Html和Css应用中的细节问题
  5. WSAData是个什么结构体用什么用
  6. ECMA 上传文件到SHarePoint 文档库
  7. Parallel类
  8. cordova之旅之初识
  9. 模板 - 动态规划 - 区间dp
  10. 蓝桥杯T37(nim博弈)