手机安全卫士——在设置中心 自定义view和自定义属性
自定义组合控件
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和自定义属性的更多相关文章
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
Android 高手进阶(21) 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明地址:http://blog.csdn.net/xiaanming/article/detail ...
- 自定义view(13)自定义属性
1.添加attrs.xml文件 在android studio下,在res/values 下新建资源文件attrs.xml 2.添加自定义的属性 在attrs.xml中添加属性,如下.其中format ...
- Android初级教程初谈自定义view自定义属性
有些时候,自己要在布局文件中重复书写大量的代码来定义一个布局.这是最基本的使用,当然要掌握:但是有些场景都去对应的布局里面写对应的属性,就显得很无力.会发现,系统自带的控件无法满足我们的要求,这个时候 ...
- Android 自定义View修炼-自定义View-带百分比进度的圆形进度条(采用自定义属性)
很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己来自定义一个能满足我们需求的View,自定义View我们需要先继承View,添加类的构造方法,重写父类View的一些方法,例如o ...
- Android查缺补漏(View篇)--自定义 View 的基本流程
View是Android很重要的一部分,常用的View有Button.TextView.EditView.ListView.GridView.各种layout等等,开发者通过对这些View的各种组合以 ...
- Android 自定义view (一)——attr 理解
前言: 自定义view是android自定义控件的核心之一,那么在学习自定义view之前,我们先来了解下自定义view的自定义属性的attr的用法吧 Android attr 是什么 (1)attr ...
- 自定义View的基本流程
1.明确需求,确定你想实现的效果2.确定是使用组合控件的形式还是全新自定义的形式,组合控件即使用多个系统控件来合成一个新控件,你比如titilebar,这种形式相对简单,参考:http://blog. ...
- 【Android - 自定义View】之自定义View浅析
1.概述 Android自定义View / ViewGroup的步骤大致如下: 1) 自定义属性: 2) 选择和设置构造方法: 3) 重写onMeasure()方法: 4) 重写onDraw()方法: ...
- Android项目 手机安全卫士(代码最全,注释最详细)之十二 设置中心的界面
------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...
随机推荐
- Tomcat的安装及使用
下面是我搭建Tomcat的过程,记录一下 下载地址:http://tomcat.apache.org/ 我下载的是8.5.30版本 安装 下载完成后解压到D盘 (配置变量的的教程网上大把随便搜) 1 ...
- 【246】◀▶IEW-Unit11
Unit 11 Transport 1. Model1题目分析 Some countries attempt to solve the problem of traffic congestion by ...
- linux私有ftp搭建与创建新用户
一.私有ftp搭建 以后补充 1. 搭建 2.修改配置文件 二.创建新用户 在linux搭建好私有ftp后,默认存放目录是 /var/ftp/ 我们有时候需要给外部公司之类的用,但又不想让他们直接在 ...
- win10 ObservableCollection 排序自动收缩问题
ObservableCollection本身是没有排序Sort功能的,不过我们可以通过冒泡排序来实现,以下是扩展功能: public static void Sort<T>(this Ob ...
- 10天彻底搞定-webpack4.0
本机存放的路径: F:\教程\10天彻底搞定-webpack4.0 联想电脑代码存放的路径: D:\MyDemos\webpack4 10天彻底搞定-webpack4.0 1.webpack课程介绍 ...
- 有两种分别用<bgsound>和<embed></embed>标签,当用<embed>插入背景音乐时可以设置宽度和高度为0,隐藏播放器。
<bgsound>: <bgsound> 是用来插入背景音乐,但只适用于 ie,其参数设定不多.如下 <bgsound src="your.mid" ...
- 小议Python3的原生协程机制
此文已由作者张耕源授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 在最近发布的 Python 3.5 版本中,官方正式引入了 async/await关键字.在 asyncio ...
- 【转】oracle的分析函数over
源地址:http://www.cnblogs.com/sumsen/archive/2012/05/30/2525800.html
- 背包dp
一大波模板正在靠近 1.01背包 问题:有n件物品和一个容量为v的背包,第i件物品的费用(即体积)是w[i],价值是v[i],求解将哪些物品装入背包可使这些物品的费用和不超过背包容量,且价值总和最大. ...
- Acwing 98-分形之城
98. 分形之城 城市的规划在城市建设中是个大问题. 不幸的是,很多城市在开始建设的时候并没有很好的规划,城市规模扩大之后规划不合理的问题就开始显现. 而这座名为 Fractal 的城市设想了这样 ...