自定义组合控件
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. BOM——浏览器对象模型(Browser Object Model)

    什么是BOM? BOM是Browser Object Model的缩写,简称浏览器对象模型 BOM提供了独立于内容而与浏览器窗口进行交互的对象 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对 ...

  2. Html.Partial 和 Html.RenderPartial 、Html.Action 和 Html.RenderAction区别

    Html.Partial 和 Html.RenderPartial不需要为视图指定路径和文件扩展名.因为运行时定位部分视图与定位正常视力使用的逻辑相同.RenderPartial不是返回字符串,而是直 ...

  3. 04_数据库升级onUpgrade&ondowngrade

    如果想操作多个数据库就不要把数据库的名字写死了 public MyOpenHelper(Context context, String name){ //第一个参数上下文 //第二个参数 数据库的名字 ...

  4. [xdoj1227]Godv的数列(crt+lucas)

    解题关键:1001=7*11*13,模数非常小,直接暴力lucas.递归次数几乎为很小的常数.最后用中国剩余定理组合一下即可. 模数很小时,一定记住lucas定理的作用 http://acm.xidi ...

  5. (十七)Spring 集成Quartz

    在使用jdk的timer时发现无法满足这次的开发需求:即无法在指定的日期进行执行任务.这便引入一个优秀的开源任务调度框架“quartz”.这里加入的是quartz-1.8.6版本.Quart的官网:h ...

  6. JavaScript代码放在HTML代码不同位置的差别

    通常情况下,JavaScript 代码是和 HTML 代码一起使用的,可以将 JavaScript 代码放置在 HTML 文档的任何地方.但放置的地方,会对 JavaScript 代码的正常执行会有一 ...

  7. ASP.NET MVC (Umbraco)中如何设置网站超时自动退出

    原文章请参考  https://edgewebware.com/2014/06/automatically-log-out-members-send-login-page-umbraco/ 在网站开发 ...

  8. uoj#401. 【CTSC2018】青蕈领主(分治FFT)

    传送门 话说分治\(FFT\)是个啥子啊--还有题目里那字好像念(蕈xùn) 首先考虑无解的情况:区间相交或者\(L_n\neq n\) 这两个都可以感性理解一下 所以区间之间只会有包含关系,我们把每 ...

  9. Zookeeper入门看这篇就够了!!

    Zookeeper是什么 官方文档上这么解释zookeeper,它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名 ...

  10. ==和equals方法

    Java程序中测试两个变量时否相等有两种方法: == 和 equals. ==判断 当使用==来判断两个变量是否相等时,如果两个变量是基本类型变量,且都是数字类型(不一定要求数据类型严格相同),则只要 ...