Android项目:手机安全卫士(4)—— 自定义(组合)控件、属性
来源:互联网 发布:电梯安全员考试软件 编辑:程序博客网 时间:2024/06/03 19:06
Android项目:手机安全卫士(4)—— 自定义(组合)控件、属性
1 总纲
手机安全卫士共有 9 个功能,我们先来看看设置界面长什么样:
大家已经发现了,第一反应就是用 ListView 实现,但是,我们仔细一看,每一个 Item 并不完全一样,况且 Item 数量也不多,所以,我们可以用自定义(组合)控件来实现,把每一个 Item 抽象出来,做成控件,之所以叫组合控件,因为这个控件中用到了很多系统控件,我们只是修改了它们的布局而已。
关于项目相关文章,请访问:
- Android 项目:手机安全卫士(1)—— 闪屏界面
- Android 项目:手机安全卫士(2)—— 版本升级
- Android 项目:手机安全卫士(3)—— 主界面布局
项目源码地址(实时更新):https://github.com/xwdoor/MobileSafe
2 自定义组合控件
先按照上图中的自动更新设置为模板进行实现,包括四个控件:两个 TextView,一个 CheckBox,一条横线。其中横线的实现思路很有意思,它也是一个 TextView,只是设置了它的高度为 1 个像素,然后这是背景为黑色即可。好了,废话不多说,开始写代码,首先创建布局文件:item_setting.xml,内容如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp"> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:text="自动更新设置" android:textColor="@android:color/black"/> <TextView android:id="@+id/tv_desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="自动更新已开启" android:layout_below="@id/tv_title" android:textColor="#b000"/> <CheckBox android:id="@+id/cb_check" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:focusableInTouchMode="false" android:focusable="false" android:layout_alignParentRight="true" android:layout_centerVertical="true"/> <TextView android:layout_width="match_parent" android:layout_height="1px" android:background="@android:color/black" android:layout_marginTop="5dp" android:layout_below="@id/tv_desc"/> </RelativeLayout>
这就是自动更新设置的 UI 实现了,注意,该布局中屏蔽了 CheckBox 的点击事件,并且不让它获取焦点。接下来就是创建自定义组件,且使用该 UI 作为界面。创建类:SettingItemView,继承自 RelativeLayout,代码如下:
/** * Created by XWdoor on 2016/3/1 001 16:19. * 博客:http://blog.csdn.net/xwdoor */ public class SettingItemView extends RelativeLayout { private TextView tvTitle; private TextView tvDesc; private CheckBox cbCheck; public SettingItemView(Context context) { super(context); initView(); } public SettingItemView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public SettingItemView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } private void initView(){ View view = View.inflate(getContext(), R.layout.item_setting,null); tvTitle = (TextView) view.findViewById(R.id.tv_title); tvDesc = (TextView) view.findViewById(R.id.tv_desc); cbCheck = (CheckBox) view.findViewById(R.id.cb_check); addView(view); } /** 设置标题 */ public void setTitle(String title){ tvTitle.setText(title); } /** 设置描述 */ public void setDesc(String desc){ tvDesc.setText(desc); } /** 是否开启 */ public boolean isChecked(){ return cbCheck.isChecked(); } /** 设置开启状态 */ public void setChecked(boolean checked){ cbCheck.setChecked(checked); } }
SettingItemView 使用了先前定义的布局,并对外公开 4 个接口,分别是:设置标题、设置描述、获取开启状态、设置开启状态。接下来就是使用它了,先是创建 SettingActivity,及其布局文件:activity_setting.xml,在布局文件中,使用刚才自定义的控件,代码如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tv_title" style="@style/TitleBar" android:text="设置"/> <!-- 自定义控件 --> <net.xwdoor.mobilesafe.view.SettingItemView android:id="@+id/siv_update" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
至此,自定义控件就弄好了,然后我们就可以像其他普通控件一样使用它了,以下是 SettingActivity 中的代码:
@Override protected void initViews(Bundle savedInstanceState) { setContentView(R.layout.activity_setting); final SettingItemView sivUpdate = (SettingItemView) findViewById(R.id.siv_update); sivUpdate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sivUpdate.setChecked(!sivUpdate.isChecked()); if(sivUpdate.isChecked()){ //若选中,开启自动更新设置 sivUpdate.setDesc("自动更新已开启"); }else { //关闭自动更新 sivUpdate.setDesc("自动更新已关闭"); } } }); }
运行结果如图:
3 自定义属性
聪明的你已经发现了,每次点击时,我们都要设置它的描述,sivUpdate.setDesc("自动更新已开启");
是已开启,sivUpdate.setDesc("自动更新已关闭");
是已关闭,一个 Item 还好,但是如果有很多个的话,管理起来就比较麻烦了,而且文字常量显示什么的属于 UI 的数据,应该在设计 UI 的时候就设置好的,所以,我们最好将这几个状态,以及标题,设置为 SettingItemView 的属性,也就是我们的自定义属性。
在 res->values
文件夹中创建资源文件:attr.xml,因为我使用的是 Android Studio,不存在该文件,所以手动创建,然后写自定义属性,代码如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="SettingItemView"> <attr name="stitle" format="string" /> <attr name="desc_on" format="string" /> <attr name="desc_off" format="string" /> </declare-styleable> </resources>
其中 name 是自定义的,format 是该属性的值类型。好了,很简单吧,接下来使用它了,首先在布局文件的根节点中,为自定义属性声明一个命名空间:xmlns:xwdoor="http://schemas.android.com/apk/res-auto"
, 其中,xwdoor 是自定义部分,这样,系统就可以找到我们的自定义属性文件的位置,然后就可以直接用了,代码如下:
<!-- 自定义控件 --> <net.xwdoor.mobilesafe.view.SettingItemView android:id="@+id/siv_update" android:layout_width="match_parent" android:layout_height="wrap_content" xwdoor:stitle="自动更新设置" xwdoor:desc_on="自动更新已开启" xwdoor:desc_off="自动更新已关闭"/>
当然,仅仅是这样,我们是看不到效果的,我们还需要在自定义控件 SettingItemView 中做一些修改才行,代码如下:
/** * Created by XWdoor on 2016/3/1 001 16:19. * 博客:http://blog.csdn.net/xwdoor */public class SettingItemView extends RelativeLayout { public static final String NAMESPACE_XWDOOR = "http://schemas.android.com/apk/res-auto"; private String mDescOff; private String mDescOn; private TextView tvTitle; private TextView tvDesc; private CheckBox cbCheck; public SettingItemView(Context context) { super(context); initView(); } public SettingItemView(Context context, AttributeSet attrs) { super(context, attrs); int attrCount = attrs.getAttributeCount(); //获取stitle属性的值 String title = attrs.getAttributeValue(NAMESPACE_XWDOOR, "stitle"); //获取关闭设置时的描述 mDescOn = attrs.getAttributeValue(NAMESPACE_XWDOOR, "desc_on"); //获取开启设置时的描述 mDescOff = attrs.getAttributeValue(NAMESPACE_XWDOOR, "desc_off"); initView(); setTitle(title); setDesc(mDescOff); } public SettingItemView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } /** 设置开启状态 */ public void setChecked(boolean checked){ cbCheck.setChecked(checked); if(checked){ setDesc(mDescOn); }else { setDesc(mDescOff); } }}
4 总结
好了,到此,我们的自定义组合控件、自定义属性就完成了,本文主要是关于 UI 设计与实现,没有多大难度,主要是知识点的整合与熟悉,且整个项目基本如此,都是熟悉 Android 开发的特性、熟悉代码风格、掌握知识点。
关于项目相关文章,请访问:
- Android 项目:手机安全卫士(1)—— 闪屏界面
- Android 项目:手机安全卫士(2)—— 版本升级
- Android 项目:手机安全卫士(3)—— 主界面布局
项目源码地址(实时更新):https://github.com/xwdoor/MobileSafe
- Android项目:手机安全卫士(4)—— 自定义(组合)控件、属性
- Android手机安全卫士(二)---设置、自定义控件属性、md5加密、手机防盗
- Android项目:手机安全卫士(5)—— 自定义弹窗
- 手机安全卫士学习之自定义组合控件
- Android项目:手机安全卫士(2)—— 版本升级
- Android项目:手机安全卫士(8)—— 管理员权限
- Android项目:手机安全卫士(14)—— 短信备份
- Android项目:手机安全卫士(16)—— 复杂 ListView
- Android自定义控件---组合控件(包括自定义属性)
- Android项目:手机安全卫士(6)—— 手机防盗设置向导(二)
- Android项目:手机安全卫士(6)—— 手机防盗设置向导(二)
- Android项目:手机安全卫士(6)—— 手机防盗设置向导
- Android项目:手机安全卫士(7)—— 手机防盗功能
- Android项目:手机安全卫士(15)—— 获取手机安装应用与存储空间
- Android手机安全卫士(一)---概述、启动、签名、主界面、自定义控件
- Android自定义xml属性,自定义(组合)控件
- 练手小项目(5)安全卫士——手机加速
- Android项目:手机安全卫士(1)—— 闪屏界面
- Java 8读取Access数据库报错的问题——用32位Java 7
- 39.layoutSubviews和drawRect调用时机的探究
- 微信JSSDK开发JAVA版实现
- Java关键字final、static使用总结
- Android.mk里添加 LOCAL_SDK_VERSION := current 后不能使用@hide API
- Android项目:手机安全卫士(4)—— 自定义(组合)控件、属性
- 依赖倒置原则
- [Andriod Monkey测试] Monkey基本参数与事件参数
- Sqoop1.99.6安装遇到的问题
- 记录yii resetful 自定义action是,设置它的请求方式
- 规范返回json格式
- 浅谈ClickableSpan , 实现TextView文本某一部分文字的点击响应
- 获取apk包名
- nginx( 设置)