package com.loaderman.settingitemviewdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View; public class MainActivity extends AppCompatActivity { private SettingItemView siv1;
private SettingItemView siv2;
private SettingItemView siv3; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
siv1 = (SettingItemView) findViewById(R.id.siv_test1);
siv2 = (SettingItemView) findViewById(R.id.siv_test2);
siv3 = (SettingItemView) findViewById(R.id.siv_test3);
siv1.setTitle("测试1");
siv1.setToggleOn(true);
siv2.setToggleOn(false); siv1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
siv1.toggle();
}
});
siv2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (siv2.isToggleOn()) {
siv2.setToggleOn(false);
} else {
siv2.setToggleOn(true);
} }
});
siv3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { }
});
}
}
package com.loaderman.settingitemviewdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView; /**
*
* <p/>
* 如果一个控件A包含了控件B, 那么A就是B的父控件, B是A的子控件; 和继承没有任何关系, 只是一种称谓而已.
* <p/>
* 自定义组合控件:
* <p/>
* 1. 写一个类继承ViewGroup(LinearLayout, RelativeLayout)
* 2. 给当前空布局添加布局对象View.inflate(getContext(), R.layout.setting_item_view, this);
* 3. 添加方法, 修改标题和背景
* 4. 维护开关状态, boolean isOpen, 点击控件,切换开关状态,并更新开关图片
*
* 自定义属性:
* 1. 在values中创建attrs.xml文件, 配置自定义属性
* 2. 在布局文件中声明命名空间, 并给相关控件配置自定义属性
* 3. 在自定义控件中, 从属性集合中获取自定义属性,并更新相关控件
*/
public class SettingItemView extends RelativeLayout { private TextView tvTitle;
private ImageView ivToggle; private boolean isOpen = false;//标记当前开关状态 private static final String NAMESPACE = "http://schemas.android.com/apk/res-auto"; public SettingItemView(Context context) {
this(context, null);
} public SettingItemView(Context context, AttributeSet attrs) {
this(context, attrs, -1);
} public SettingItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(); //1.从AttributeSet中取出自定义的属性
String title = attrs.getAttributeValue(NAMESPACE, "title");
int bgId = attrs.getAttributeIntValue(NAMESPACE, "bg", 0);//0,1,2
boolean showToggle = attrs.getAttributeBooleanValue(NAMESPACE, "show_toggle", true); //2.根据自定义属性的值更新相关控件
setTitle(title);//修改标题 //修改背景
switch (bgId) {
case 0:
setBackgroundResource(R.drawable.first_selector);
break;
case 1:
setBackgroundResource(R.drawable.middle_selector);
break;
case 2:
setBackgroundResource(R.drawable.last_selector);
break;
} //控制开关的显示和隐藏
ivToggle.setVisibility(showToggle ? VISIBLE : GONE); } private void initView() {
//给当前空布局添加布局对象
//A view group that will be the parent
//参3: 如果是null, 表示加载出的布局对象没有父控件, 绝大部分情况下都传null
//如果是this,代表在加载布局对象时, 以当前的SettingItemView为父控件; 这样写也可以实现给SettingItemView填充布局的效果
View view = View.inflate(getContext(), R.layout.setting_item_view, this);
//addView(view); tvTitle = (TextView) view.findViewById(R.id.tv_title);
ivToggle = (ImageView) view.findViewById(R.id.iv_toggle);
} //公开一个方法,供外界修改标题
public void setTitle(String title) {
tvTitle.setText(title);
} //获取当前开关状态
public boolean isToggleOn() {
return isOpen;
} //修改当前开关状态
public void setToggleOn(boolean isOpen) {
this.isOpen = isOpen;
System.out.println("当前开关状态:" + isOpen);
//修改开关图片
ivToggle.setImageResource(isOpen ? R.drawable.on : R.drawable.off);
} //如果开,则关; 如果关,则开
public void toggle() {
setToggleOn(!isOpen);
}
}

自定义属性.在values/下新建attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SettingItemView">
<!--自定义标题属性-->
<attr name="title" format="string"/>
<!--自定义背景属性, 枚举-->
<attr name="bg">
<enum name="first" value="0" />
<enum name="middle" value="1" />
<enum name="last" value="2" />
</attr> <!--自定义是否显示开关的属性-->
<attr name="show_toggle" format="boolean"/> </declare-styleable> </resources>

activtity_main.xml,使用自定义属性记得添加命名空间

 xmlns:YOU_NAME="http://schemas.android.com/apk/res-auto"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:loaderman="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp"
tools:context="com.loaderman.settingitemviewdemo.MainActivity"> <com.loaderman.settingitemviewdemo.SettingItemView
android:id="@+id/siv_test1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
loaderman:bg="first"
/>
<com.loaderman.settingitemviewdemo.SettingItemView
android:id="@+id/siv_test2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
loaderman:title="测试2"
loaderman:bg="middle"
/> <com.loaderman.settingitemviewdemo.SettingItemView
android:id="@+id/siv_test3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
loaderman:bg="last"
loaderman:title="测试3"
loaderman:show_toggle="false"
/>
</LinearLayout>

setting_item_view.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"
android:paddingBottom="10dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="10dp"
> <TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textColor="@color/black"
android:textSize="18sp"
/> <ImageView
android:id="@+id/iv_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/off"
/> </RelativeLayout>

实现效果:


自定义组合控件SettingItemView的简单实现的更多相关文章

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

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

  2. 安卓自定义组合控件--toolbar

    最近在学习安卓APP的开发,用到了toolbar这个控件, 最开始使用时include layout这种方法,不过感觉封装性不好,就又改成了自定义组合控件的方式. 使用的工具为android stud ...

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

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

  4. Android开发之自定义组合控件

    自定义组合控件的步骤1.自定义一个View,继承ViewGroup,比如RelativeLayout2.编写组合控件的布局文件,在自定义的view中加载(使用View.inflate())3.自定义属 ...

  5. 自定义组合控件,适配器原理-Day31

    自定义组合控件,适配器原理-Day31 mobile2.1 主页定义 手机上锁功能 1.弹出设置密码框. 手机下载进度 自定定义控件 控件的属性其实就是控件类一个属性设置属性调用类的set方法方法, ...

  6. Android Studio自定义组合控件

    在Android的开发中,为了能够服用代码,会把有一定共有特点的控件组合在一起定义成一个自定义组合控件. 本文就详细讲述这一过程.虽然这样的View的组合有一个粒度的问题.粒度太大了无法复用,粒度太小 ...

  7. Android中自定义组合控件

    Android中自定义控件的情况非常多,一般自定义控件可以分为两种:继承控件及组合控件.前者是通过继承View或其子类,重写方法实现自定义的显示及事件处理方式:后者是通过组合已有的控件,来实现结构的简 ...

  8. Android自定义控件之自定义组合控件(三)

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

  9. Android View体系(十)自定义组合控件

    相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源 ...

随机推荐

  1. DHCP显示

    两种PXE启动芯片 开机显示:Inter® Boot Agent GE V1.2.45或者Intel UNDI PXE2.0 (Build 082):其中UNDI是Universal Network ...

  2. deep_learning_backprop

    反向传播理解–从抽象到具体 神经网络从计算的角度看,数据是从底层输入,经过每一层,根据与该层之间的权重计算以一个中间结果,这个中间结果再经过一个非线性激活函数作用,得到该层的输出结果,然后把该层的输出 ...

  3. 异步通信&同步通信

    首先是两者的不同: 同步通信要求接收端时钟频率和发送端时钟频率一致,发送端发送连续的比特流:异步通信时不要求接收端时钟和发送端时钟同步,发送端发送完一个字节后,可经过任意长的时间间隔再发送下一个字节. ...

  4. CF #546 D.E

    D coun[i]表示[i]这个数右边有多少个数j能和他组成题中所给的二元组(i,j) 如果一个数的coun[i]=n-i-ans 那么说明他可以与最后一个交换 同时不计算贡献 因为它是向右走的 对左 ...

  5. 布隆算法(BloomFilter)

          BloomFilter算法,是一种大数据排重算法.在一个数据量很大的集合里,能准确断定一个对象不在集合里:判断一个对象有可能在集合里,而且占用的空间不大.它不适合那种要求准确率很高的情况, ...

  6. 精选30道Java多线程面试题

    1.线程和进程的区别 进程是应用程序的执行实例.比如说,当你双击的Microsoft Word的图标,你就开始运行的Word的进程.线程是执行进程中的路径.另外,一个过程可以包含多个线程.启动Word ...

  7. tornado框架自定义中间件过程中的一些基础技术(1)

    为了检查当前请求是否在用户的权限列表中,我们需要获取uri(也就是当前链接),下列代码说明了获取的过程,也证明了python魔术方法的重要性class testHandler(RequestHandl ...

  8. C# 数据类型转化为byte数组

    short数据与byte数组互转 public byte[] ShortToByte(short value) { return BitConverter.GetBytes(value); } pub ...

  9. python获取某路径下某扩展名的所有文件名和文件个数

    # -*- coding: utf-8 -*- # @Time : 19-1-10 下午10:02 # @Author : Felix Wang import os def get_file_coun ...

  10. mac 强行关掉php

    sudo pkill -INT -o php-fpm//重启php sudo php-fpm //mac brew安装的php可以使用这个开启brew services start homebrew/ ...