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. C++2.0新特性(四)——<decltype、lambda>

    一.关键字decltype 引入新关键字decltype可以让编译器找出表达式的类型,为了区别typeof,以下做一个概念区分: typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型 ...

  2. JavaWeb之基础(2) —— HTTP协议

    1. 粗讲什么是HTTP协议 HTTP协议的全程是Hyper Text Transfer Protocol,超文本传输协议,见名知意,这是个用来控制传输超文本的协议.下面就来简单说说什么是HTTP协议 ...

  3. select,poll,epoll最简单的解释

    从事服务端开发,少不了要接触网络编程.epoll 作为 Linux 下高性能网络服务器的必备技术至关重要,nginx.Redis.Skynet 和大部分游戏服务器都使用到这一多路复用技术. epoll ...

  4. csapp网络编程初学笔记

    csapp网络编程初学笔记 客户端-服务器编程模型 每个网络应用都是基于客户端-服务器模型,服务器管理某种资源,并且通过操作来为它的客户提供某种服务 客户端-服务器模型中的基本操作是transacti ...

  5. Java垃圾回收(java GC)

    一.GC的阶段 对每个对象而言,垃圾回收分为两个阶段:finalization和reclamation. finalization: 指运行这个对象的finalize的方法. reclamation: ...

  6. 覆盖elementui样式

    前台以表格形式展示后台数据,图片或视频点击后弹出框播放,用el-dialog实现. 希望播放视频的时候不显示dialog的背景那些. 尝试 scoped 无果 <style lang=" ...

  7. iPhone 照片为heic格式怎么处理?

      解决办法: 永久解决:进入 相机设置 为 兼容模式即可 这样设置以后拍出来的就是jpg格式啦. 之前的heic的照片可以用,格式工厂 批量转化一下.   文章来源:刘俊涛的博客 欢迎关注公众号.留 ...

  8. cache-control: max-age=1,s-maxage=1

    cache-control: max-age=1,s-maxage=1

  9. Spring Boot CLI——centos7

    Spring Boot是一个命令行工具,用于使用Spring进行快速原型搭建.它允许你运行Groovy脚本,这意味着你可以使用类Java的语法,并且没有那么多的模板代码. 所有版本下载地址这里下载的版 ...

  10. Springmvc request response log

    Log Incoming Requests In Spring | Java Development Journalhttps://www.javadevjournal.com/spring/log- ...