在开发过程中,会经常遇到这样的需求:上面有很多的输入控件,等所有的输入都合法后,按钮才能自动变成enabled的状态,才能继续下一步的操作。

下面是一种用观察者模式实现的一种解决方案。

button代码:

public class KWButton extends Button implements Observer {

    private LinkedHashSet<Verifiable> mVerifiers = new LinkedHashSet<Verifiable>();

    public KWButton(Context context) {
super(context);
initView();
} public KWButton(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
} public KWButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
} private void initView() {
// 初始化view
} /**
* 添加观察者
*
* @param verifier
*/
public void observer(Verifiable verifier) {
if (this.isEnabled()) {
this.setEnabled(false);
} // 校验:如果当前verifier属于view 但是 不可显示则不做监听
if ((verifier instanceof View)
&& ((View) verifier).getVisibility() != View.VISIBLE) {
update(null, null);
return;
}
if (verifier != null && !mVerifiers.contains(verifier)) {
mVerifiers.add(verifier);
//精华所在
verifier.addObserver(this);
} update(null, null);
} @Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
} /**
* 解除观察
*
* @param verifier
*/
public void removeObserver(Verifiable verifier) { if (verifier != null) {
mVerifiers.remove(verifier);
this.update(null, null);
}
} /**
* 清空观察者
*/
public void clearObserver() {
if (!ListUtil.isEmpty(mVerifiers)) {
mVerifiers.clear();
mAutoPerformClick = false;
this.update(null, null);
}
} @Override
public void update(Observable observable, Object data) {
if (mAutoPerformClick) {
if (!ListUtil.isEmpty(mVerifiers)) {
if (isVerify()) {
this.postDelayed(new Runnable() { @Override
public void run() {
performClick();
}
}, PERFORM_DELAY_TIME);
}
}
} else {
for (Verifiable verifier : mVerifiers) {
if (verifier.isBlank()) {
KWButton.this.setEnabled(false);
return;
}
}
KWButton.this.setEnabled(true);
}
} /**
* 是否已通过验证
*
* @return
*/
private boolean isVerify() {
for (Verifiable verifier : mVerifiers) {
if (!verifier.verify()) {
return false;
}
}
return true;
}
}

校验接口:

/**
* 校验接口
*
*/
public interface Verifiable {
/**
* 校验
*
* @return
*/
boolean verify();
boolean isBlank();
void addObserver(Observer obj);
}

输入控件:

/**
* 输入控件
*/
public class NeedCheckInput extends EditText implements Verifiable { private Context mContext;
/**
* 校验
*/
private Observer mVerifyObserver = null; public NeedCheckInput(Context context) {
super(context);
mContext = context;
init();
} public NeedCheckInput(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init();
} @SuppressLint("InflateParams")
private void init() {
// 初始化view 代码
}
/*
// 通知观察者,控件状态已经改变,update一次,就检查一次
if (mVerifyObserver != null) {
mVerifyObserver.update(null, null);
}
*/ @Override
public boolean verify() {
//添加校验规则 true:校验通过 false:校验不通过
return !TextUtils.isEmpty(this.getText().toString());
} @Override
public boolean isBlank() {
return ....;
} @Override
public void addObserver(Observer obj) {
mVerifyObserver = obj;
} }

示例代码:

KWButton button  = new KWButton(context);
NeedCheckInput input1 = new NeedCheckInput(context);
NeedCheckInput input2 = new NeedCheckInput(context); button.addObserver(input1);
button.addObserver(input2);

这样就可以做到检查输入了。

Android 检查输入的更多相关文章

  1. android键盘输入读取

    android键盘输入读取  监控android键盘输入方式有两种,一种在java层实现,重写onKeyDown和onKeyUp方法.另一种是在jni层实现,监控/dev/input/event0键盘 ...

  2. Android系统--输入系统(五)输入系统框架

    Android系统--输入系统(五)输入系统框架 1. Android设备使用场景: 假设一个Android平板,APP功能.系统功能(开机关机.调节音量).外接设备功能(键盘.触摸屏.USB外接键盘 ...

  3. Android系统--输入系统(六)模拟输入驱动程序

    Android系统--输入系统(六)模拟输入驱动程序 1. 回顾输入子系统 简单字符设备驱动:应用程序通过调用驱动所实现的函数使能硬件. 输入子系统:由于有多个应用程序使用输入子系统,故肯定使用的是早 ...

  4. Android系统--输入系统(七)Reader_Dispatcher线程启动分析

    Android系统--输入系统(七)Reader_Dispatcher线程启动分析 1. Reader/Dispatcher的引入 对于输入系统来说,将会创建两个线程: Reader线程(读取事件) ...

  5. Android系统--输入系统(八)Reader线程_使用EventHub读取事件

    Android系统--输入系统(八)Reader线程_使用EventHub读取事件 1. Reader线程工作流程 获得事件 size_t count = mEventHub->getEvent ...

  6. Android系统--输入系统(九)Reader线程_核心类及配置文件

    Android系统--输入系统(九)Reader线程_核心类及配置文件 1. Reader线程核心类--EventHub 1.1 Reader线程核心结构体 实例化对象:mEventHub--表示多个 ...

  7. Android系统--输入系统(十)Reader线程_核心类及配置文件深入分析

    Android系统--输入系统(十)Reader线程_核心类及配置文件深入分析 0. 前言 个人认为该知识点阅读Android源代码会不仅容易走进死胡同,并且效果并不好,前脚看完后脚忘记,故进行总结, ...

  8. Android系统--输入系统(十一)Reader线程_简单处理

    Android系统--输入系统(十一)Reader线程_简单处理 1. 引入 Reader线程主要负责三件事情 获得输入事件 简单处理 上传给Dispatch线程 InputReader.cpp vo ...

  9. Android系统--输入系统(十二)Dispatch线程_总体框架

    Android系统--输入系统(十二)Dispatch线程_总体框架 1. Dispatch线程框架 我们知道Dispatch线程是分发之意,那么便可以引入两个问题:1. 发什么;2. 发给谁.这两个 ...

随机推荐

  1. 设置eclipse中的${user}

    打开eclipse根目录找到eclipse.ini文件增加初始配置: -Duser.name=snzigod@hotmail.com 重启eclipse后${user}变量的值就变成了snzigod@ ...

  2. Linux学习-可唤醒停机期间的工作任务

    什么是 anacron anacron 并不是用来取代 crontab 的,anacron 存在的目的就在于我们上头提到的,在处理非 24 小 时一直启动的 Linux 系统的 crontab 的执行 ...

  3. git push后是空目录,且提示modified content, untracked content

    最近往自己的github传代码时,每一步都正常,但最后push上去之后是空目录,且在本地执行git status时提示: 后来发现是由于push的工程下本来就有个.git目录,所以才导致push上去的 ...

  4. #ifndef、#def、#endif说明

    你所遇到的这几个宏是为了进行条件编译.一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一 部分内容指定编译的条件,这就是“条件编译”.有时,希望 ...

  5. Java构造器(construtor)与垃圾收集器(GB)

    在Java中,程序员会在乎内存中的两块空间. 堆(heap)和栈(stack). 当java虚拟机启动时, 它会从底层的操作系统取得一块内存, 并且以此块内存来执行java程序. 在Java中, 实例 ...

  6. mysql update连表

    UPDATE price_air_item t1 LEFT JOIN order_item t2 ON t1.ORDER_ITEM_ID = t2.ORDER_ITEM_ID SET t1.BUYER ...

  7. c中#与##的应用思考

    c中#与##的应用思考 原创 2014年02月25日 22:01:35 927 一. 思考出处 在读<<linux 0.12完全剖析>>初始化部分, init进程是通过fork ...

  8. python常用方法总结

    1.os模块的路径拼接: import os now_path=os.path.abspath(__file__)#当前运行文件的路径 print(now_path) uppeer_path=os.p ...

  9. JS进行人民币大小写转换

    //数字金额大写转换(可以处理整数,小数,负数) function upDigit() { digit=$("#digit").html(); n=digit.replace(/\ ...

  10. 剑指offer 面试题38

    面试题38:数字在排序数组中出现的次数 题目:统计一个数字在排序数组中出现的次数.例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4. 主要的思路是进 ...