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. Java ArrayList对象集合去重

    import java.util.ArrayList; import java.util.Iterator; public class StringSampleDemo { public static ...

  2. 【随记】安装SQL Server 2008 R2 提示创建usersettings/microsoft.sqlserver.configuration.landingpage.properties.se

    在安装SQL Server 2008 R2 提示创建usersettings/microsoft.sqlserver.configuration.landingpage.properties.se.. ...

  3. SpringMVC从Session域中获取值

    SpringMVC从Session域中获取值 SpringMVC环境自行搭建 第一步:前端页面 第二步.后台代码 第三步.响应视图 第四步.在当前处理器所在的类设置@SessionAttributes ...

  4. iframe中用到的例子

    <view:qrytr>         <view:qrytd colspan="4">     <iframe id="ccbl&quo ...

  5. 深入理解JVM虚拟机10:JVM常用参数以及调优实践

    转自http://www.rowkey.me/blog/2016/11/02/java-profile/?hmsr=toutiao.io&utm_medium=toutiao.io&u ...

  6. weblogic介绍

    快速阅读 介绍weblogic中间件,以及自身架构和几个基本概念,如何下载,安装等后面再详细介绍 . 什么是weblogic WebLogic最早由 WebLogic Inc. 开发,后并入BEA 公 ...

  7. YARN 状态机可视化,生成状态机图

    由于在windows下面,配置好所有 编译hadoop2.4.1源码 的环境会很麻烦,好在我之前已经把hadoop2.4.1的源码成功导入eclipse,并解决了所有错误提示,所以我就可以在eclip ...

  8. RabbitMQ Management API调用

    RabbitMQ在运行时,偶尔会有一些死信,即消息未正常消费,造成消息积压在消息队列中, 一直卡住,重复循环消费原来的消息队列 那么就需要有一种机制,来查看RabbitMQ是否有消息未正常消费,从而让 ...

  9. 关于Android8.0 静态注册广播 行为变更的说明。

    Andorid 8.0 对广播的使用做了变更. 当广播接收器使用静态注册方式使用时,除了一些例外,这个接收器接收不到隐式广播. 注意这个“隐式”是重点. 看了网上几篇文章,对这个变更理解有误.错误的理 ...

  10. Code Quality and Security | SonarQube

    SonarQube - 国内版 Binghttps://cn.bing.com/search?FORM=U227DF&PC=U227&q=SonarQube Code Quality ...