自定义组合控件
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();
} }

手机安全卫士——在设置中心 自定义view和自定义属性的更多相关文章

  1. Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

      Android 高手进阶(21)  版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明地址:http://blog.csdn.net/xiaanming/article/detail ...

  2. 自定义view(13)自定义属性

    1.添加attrs.xml文件 在android studio下,在res/values 下新建资源文件attrs.xml 2.添加自定义的属性 在attrs.xml中添加属性,如下.其中format ...

  3. Android初级教程初谈自定义view自定义属性

    有些时候,自己要在布局文件中重复书写大量的代码来定义一个布局.这是最基本的使用,当然要掌握:但是有些场景都去对应的布局里面写对应的属性,就显得很无力.会发现,系统自带的控件无法满足我们的要求,这个时候 ...

  4. Android 自定义View修炼-自定义View-带百分比进度的圆形进度条(采用自定义属性)

    很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己来自定义一个能满足我们需求的View,自定义View我们需要先继承View,添加类的构造方法,重写父类View的一些方法,例如o ...

  5. Android查缺补漏(View篇)--自定义 View 的基本流程

    View是Android很重要的一部分,常用的View有Button.TextView.EditView.ListView.GridView.各种layout等等,开发者通过对这些View的各种组合以 ...

  6. Android 自定义view (一)——attr 理解

    前言: 自定义view是android自定义控件的核心之一,那么在学习自定义view之前,我们先来了解下自定义view的自定义属性的attr的用法吧 Android attr 是什么 (1)attr ...

  7. 自定义View的基本流程

    1.明确需求,确定你想实现的效果2.确定是使用组合控件的形式还是全新自定义的形式,组合控件即使用多个系统控件来合成一个新控件,你比如titilebar,这种形式相对简单,参考:http://blog. ...

  8. 【Android - 自定义View】之自定义View浅析

    1.概述 Android自定义View / ViewGroup的步骤大致如下: 1) 自定义属性: 2) 选择和设置构造方法: 3) 重写onMeasure()方法: 4) 重写onDraw()方法: ...

  9. Android项目 手机安全卫士(代码最全,注释最详细)之十二 设置中心的界面

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...

随机推荐

  1. DBS:目录

    ylbtech-DBS:目录 1.返回顶部 1.   2. 2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   7.返回顶部   8.返回顶部   9.返回顶 ...

  2. ActiveRecord 的类型初始值设定项引发异常

    最近在研究ActiveRecord网上有很多贴子讲怎么用的.但自己照做就是出错. 最终定位在配置文件出错.应该是ActiveRecord有更新的原因.在国外的网站把配置复制了一份替换.问题解决了.我用 ...

  3. codec can't decode byte 0xe6 in position 0: ordinal not in range

    ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)] 错误: 实例 "linux-cor ...

  4. 《Java多线程编程核心技术》读后感(十三)

    类InheritableThreadLocal的使用 使用类InheritableThreadLocal可以在子线程中取得父线程继承下来的值 值继承 package Third; import jav ...

  5. 2、CDH组件安装

    一.zookeeper 1.安装 继续->完成: 二.HDFS 1.安装 继续->完成: 三.yarn.hive 1.安装yarn 继续->完成: 2.安装hive 继续->完 ...

  6. Python模拟登录代码

    注:访问http://127.0.0.1:8080/user/6,总是会要求必须有登录权限,也就是,若未登录,访问该页面,会跳转到登陆页面. 全自动模拟登录 半自动模拟登录:

  7. 杭电1002_A + B Problem II

    这是该题的链接http://acm.hdu.edu.cn/showproblem.php?pid=1002 具体的题的内容就不过多描述了,想必你已经知道了,当我看完这道题后就知道咋写了,可是这道题从开 ...

  8. ubuntu18.04安装配置boost库

    1.官网下载(www.boost.org) 2.解压并进入文件夹 3.使用命令./bootstrap.sh,可以通过加上--prefix help 4.使用命令./b2 install etc.如果运 ...

  9. katalon studio配置git与git项目创建

    katalon 是一款在2015年诞生的可以安装在windows.macOS.linux操作系统上,基于selenium 和 Appium 测试框架,并集成了这些框架的优点的自动化测试工具.关于这个工 ...

  10. POJ 3299

    #include <iostream> #include "math.h" double e2h(double e) { return 0.5555*(e-10.0); ...