1.需求介绍

将已经编写好的布局文件,抽取到一个类中去做管理,下次还需要使用类似布局时,直接使用该组合控件的对象。

优点:可复用。

例如要重复利用以下布局:

<RelativeLayout
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <TextView
android:id="@+id/tvSet_title"
android:textSize="18dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="自动更新设置" /> <TextView
android:id="@+id/tvSet_def"
android:textSize="18dp"
android:textColor="#000"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvSet_title"
android:text="自动更新已关闭" /> <!--android:layout_alignParentRight="true" 设置控件在父控件的最右边-->
<!--android:layout_centerVertical="true" 垂直方向居中-->
<CheckBox
android:id="@+id/cbSet_1"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> <!--实现分割线的效果-->
<View
android:background="#000"
android:layout_marginTop="5dp"
android:layout_below="@id/tvSet_def"
android:layout_width="match_parent"
android:layout_height="1dp"/>
</RelativeLayout>

2.事件传递规则与相应规则

SettingActivity对应布局文件的根布局获取点击事件
此事件传递给SettingItemView控件

(1)点击在SettingItemView非CheckBox区域,事件就由SettingItemView去做响应
(2)点击在SettingItemView中CheckBox区域,事件就由SettingItemView传递给CheckBox,由CheckBox去做响应
CheckBox响应当前的点击事件,则SettingItemView就不能再去响应此事件,不能调用onClick方法,去改变状态

解决此问题的方案为:不让checkBox响应点击事件

3.自定义属性

在复用SettingItemView的时候,每一个条目对应的标示,描述内容都不一致。

解决方案:给自定义控件SettingItemView定义属性

(1)在res\values目录下新建attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SetttingItemView">
<attr name="destitle" format="string"/>
<attr name="desoff" format="string"/>
<attr name="deson" format="string"/>
</declare-styleable>
</resources>

(2)自定义属性的使用

后3个属性就是自定义属性

safeguard替换掉原有android

com.example.administrator.test62360safeguard(工程的包名)必须这样编写,替换掉了android,代表当前应用自定义属性

<com.example.administrator.test62360safeguard.Utils.SetttingItemView
xmlns:safeguard="http://schemas.android.com/apk/res/com.example.administrator.test62360safeguard"
android:id="@+id/siv_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
safeguard:destitle="自动更新设置"
safeguard:desoff="自动更新已关闭"
safeguard:deson="自动更新已开启"
>

(3)获取属性值

在自定义控件类(SetttingItemView)中创建获取属性值的方法

/**
* @param attrs 自定义属性值
*/
private void initAttrs(AttributeSet attrs) {
destitle=attrs.getAttributeValue(NAMESPACE,"destitle");
desoff=attrs.getAttributeValue(NAMESPACE,"desoff");
deson=attrs.getAttributeValue(NAMESPACE,"deson");
}

4.实现步骤

(1)将组合控件的布局,抽取到一个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="wrap_content"> <RelativeLayout
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <TextView
android:id="@+id/tvSet_title"
android:textSize="18dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="自动更新设置" /> <TextView
android:id="@+id/tvSet_def"
android:textSize="18dp"
android:textColor="#000"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tvSet_title"
android:text="自动更新已关闭" /> <!--android:layout_alignParentRight="true" 设置控件在父控件的最右边-->
<!--android:layout_centerVertical="true" 垂直方向居中-->
<!--android:clickable="false"-->
<!--android:focusable="false"-->
<!--android:focusableInTouchMode="false" 让当前的CheckBox不能被点击,即不能相应事件-->
<CheckBox
android:id="@+id/cbSet_1"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> <!--实现分割线的效果-->
<View
android:background="#000"
android:layout_marginTop="5dp"
android:layout_below="@id/tvSet_def"
android:layout_width="match_parent"
android:layout_height="1dp"/>
</RelativeLayout>
</RelativeLayout>

(2)通过一个单独的类,去加载此段布局文件

获取自定义的属性值,并将属性值的内容赋值给自定义控件;

package com.example.administrator.test62360safeguard.Utils;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView; import com.example.administrator.test62360safeguard.R; //通过一个单独的类,去加载此段布局文件,由于布局采用相对布局,所以此类需继承RelativeLayout
public class SetttingItemView extends RelativeLayout {
CheckBox cbSet_1;
TextView tvSet_def;
String destitle;
String desoff;
String deson;
private static final String NAMESPACE="http://schemas.android.com/apk/res/com.example.administrator.test62360safeguard";
//使得该方法调用第二个构造方法
public SetttingItemView(Context context) {
this(context,null);
} //使得该方法调用第三个构造方法
public SetttingItemView(Context context, AttributeSet attrs) {
this(context, attrs,0);
} public SetttingItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//将xml转化为一个view对象,直接添加到当前的SetttingItemView对应的view中
View.inflate(context, R.layout.setting_item_view,this);
TextView tvSet_title=findViewById(R.id.tvSet_title);
tvSet_def=findViewById(R.id.tvSet_def);
cbSet_1=findViewById(R.id.cbSet_1); //获取自定义以及原生属性
initAttrs(attrs);
//获取布局文件中定义的字符串,赋值给自定义组合控件的标题
tvSet_title.setText(destitle);
tvSet_def.setText(desoff);
} /**
* @param attrs 自定义属性值
*/
private void initAttrs(AttributeSet attrs) {
destitle=attrs.getAttributeValue(NAMESPACE,"destitle");
desoff=attrs.getAttributeValue(NAMESPACE,"desoff");
deson=attrs.getAttributeValue(NAMESPACE,"deson");
} //判断SetttingItemView组件是否被选中,true(选中),false(未选中)
public boolean isChecked(){
//SetttingItemView组件是否被选中与该自定义组件内部的checkbox的状态绑定
return cbSet_1.isChecked();
} //切换选中状态
public void setChecked(boolean isCheck){
if(isCheck){
cbSet_1.setChecked(isCheck);
tvSet_def.setText(deson);
}else {
cbSet_1.setChecked(isCheck);
tvSet_def.setText(desoff);
}
} }

(3)自定义组合控件在xml使用

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SettingActivity"> <!--调用可复用的样式-->
<TextView
style="@style/TitleStyle"
android:text="设置中心"/>
<!--使用自定义的组合控件-->
<com.example.administrator.test62360safeguard.Utils.SetttingItemView
xmlns:safeguard="http://schemas.android.com/apk/res/com.example.administrator.test62360safeguard"
android:id="@+id/siv_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
safeguard:destitle="自动更新设置"
safeguard:desoff="自动更新已关闭"
safeguard:deson="自动更新已开启"
>
</com.example.administrator.test62360safeguard.Utils.SetttingItemView> <com.example.administrator.test62360safeguard.Utils.SetttingItemView
xmlns:safeguard="http://schemas.android.com/apk/res/com.example.administrator.test62360safeguard" android:layout_width="match_parent"
android:layout_height="wrap_content"
safeguard:destitle="电话归属地显示设置"
safeguard:desoff="归属地显示已关闭"
safeguard:deson="归属地显示已开启"
>
</com.example.administrator.test62360safeguard.Utils.SetttingItemView> </LinearLayout>

(4)UI界面应用

package com.example.administrator.test62360safeguard;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View; import com.example.administrator.test62360safeguard.ViewUtil.SetttingItemView; public class SettingActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
initUpdate();
} private void initUpdate() {
final SetttingItemView siv_update=findViewById(R.id.siv_update);
siv_update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取之前的选中状态
boolean isCheck=siv_update.isChecked();
//将原有状态取反,设置为当前状态
siv_update.setChecked(!isCheck);
}
});
}
}

5.效果图

       

014 Android 自定义组合控件的更多相关文章

  1. Android自定义组合控件详细示例 (附完整源码)

    在我们平时的Android开发中,有时候原生的控件无法满足我们的需求,或者经常用到几个控件组合在一起来使用.这个时候,我们就可以根据自己的需求创建自定义的控件了,一般通过继承View或其子类来实现. ...

  2. Android自定义组合控件

    今天和大家分享下组合控件的使用.很多时候android自定义控件并不能满足需求,如何做呢?很多方法,可以自己绘制一个,可以通过继承基础控件来重写某些环节,当然也可以将控件组合成一个新控件,这也是最方便 ...

  3. Android自定义组合控件内子控件无法显示问题

    今天自定义了一个组合控件,与到了个奇葩问题: 我自定义了一个RelativeLayout,这个layout内有多个子控件.但奇怪的是这些子控件一直显示不出来.调试了一下午,竟然是因为在获取(infla ...

  4. (转)android自定义组合控件

    原文地址:http://mypyg.iteye.com/blog/968646 目标:实现textview和ImageButton组合,可以通过Xml设置自定义控件的属性. 1.控件布局:以Linea ...

  5. android 自定义组合控件 顶部导航栏

    在软件开发过程中,经常见到,就是APP 的标题栏样式几乎都是一样的,只是文字不同而已,两边图标不同.为了减少重复代码,提高效率, 方便大家使用,我们把标题栏通过组合的方式定义成一个控件. 例下图: 点 ...

  6. Android自定义组合控件:UIScrollLayout(支持界面滑动及左右菜单滑动)

    一.前言: 我之前很早的时候,写过一篇<左右滑出菜单>的文章: http://blog.csdn.net/qingye_love/article/details/8776650 用的是对V ...

  7. Android 自定义组合控件

    1, you need to add this kind of code to the constructors of your custom view which must extend ViewG ...

  8. Android自定义控件之自定义组合控件

    前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...

  9. Android 手机卫士--自定义组合控件构件布局结构

    由于设置中心条目中的布局都很类似,所以可以考虑使用自定义组合控件来简化实现 本文地址:http://www.cnblogs.com/wuyudong/p/5909043.html,转载请注明源地址. ...

随机推荐

  1. bootstrap select 多选的用法,取值和赋值(取消默认选择第一个的对勾)

    h5自带的select标签可以实现按住ctrl键多选的功能,但是样式及其难看. bootstrap select是很好用的前端插件 ​ 首先引入bootstrap和bootstrap-select的c ...

  2. docker-machine 远程安装docker

    base=https://github.com/docker/machine/releases/download/v0.14.0 && curl -L $base/docker-mac ...

  3. Oracle中查询走索引的情况

    1.对返回的行无任何限定条件,即没有where子句 2.未对数据表与任何索引主列相对应的行限定条件例如:在City-State-Zip列创建了三列复合索引,那么仅对State列限定条件不能使用这个索引 ...

  4. docker运行puppeteer出现defucnt僵尸进程

    其实这是docker的一个bug,就是在运行前加--init即可,注意这个在mac中没有只在linux上有. docker run --init -d ..... 具体内容参见:https://sta ...

  5. CORS & CSP笔记

    1.CORS & CSP 浏览器跨域相关的安全策略主要存在于两个方面: 浏览器是否发送ajax 浏览器是否加载返回数据 假设从a.com 向b.com发送ajax请求.此时浏览器当前页面为a. ...

  6. 小福bbs-冲刺总结

    [小福bbs-冲刺总结] 这个作业属于哪个课程 班级链接 这个作业要求在哪里 作业要求的链接 团队名称 小福bbs 这个作业的目标 冲刺总结 作业的正文 小福bbs-冲刺总结 其他参考文献 面向百度和 ...

  7. 4 个用于执行高级数学计算的 JavaScript 库

    在使用JavaScript执行数学方面的任务时,往往要用到浮点运算,且需要精确到某位小数,这就容易造成错误,而且会相当费时.因此,如果你需要做一些高精度的数学计算的编程工作,比如财务或科学计算,那么你 ...

  8. Java中JVM内存结构

    Java中JVM内存结构 线程共享区 方法区: 又名静态成员区域,包含整个程序的 class.static 成员等,类本身的字节码是静态的:它会被所有的线程共享和是全区级别的: 属于共享内存区域,存储 ...

  9. 微信小程序wx.uploadFile的两个坑

    -- setImage:function(e){ var _this = this //坑1 wx.chooseImage({ count: , sizeType: ['original', 'com ...

  10. ping 域名