在开发过程中,会经常遇到这样的需求:上面有很多的输入控件,等所有的输入都合法后,按钮才能自动变成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. 全网最详细python中socket套接字send与sendall的区别

    将数据发送到套接字. 套接字必须连接到远程套接字.  返回发送的字节数. 应用程序负责检查是否已发送所有数据; 如果仅传输了一些数据, 则应用程序需要尝试传递剩余数据.(需要用户自己完成) 将数据发送 ...

  2. MongoDB学习-->Gridfs分布式存储&DBRef关联查询

    mongodb自带的一个分布式文件系统 fs.files _id filename md5 size uploaddate contenttype metadata {"user_id&qu ...

  3. 十分钟了解HTTPS协议

    概念 HTTP协议上添加一层SSL/TLS协议进行加密,保证用户与web站点之间的数据传输时密文,而不是明文. PS:HTTPS协议 = HTTP协议 + SSL(Secure Sockets Lay ...

  4. python - web自动化测试 - 文件上传操作

    # 12. 上传操作## (1)如果是input可以直接输入路径的,直接使用send_keys输入路径# (2)非input标签的,需要借助第三方工具:# A. AutoIt : 调用其生成的au3或 ...

  5. AWK 用法

     awk 用法:awk ' pattern {action} ' 变量名 含义 ARGC 命令行变元个数 ARGV 命令行变元数组 FILENAME 当前输入文件名 FNR 当前文件中的记录号 FS ...

  6. C++大数相加

    c++ string sum(string s1,string s2) { if(s1.length()<s2.length()) { string temp=s1; s1=s2; s2=tem ...

  7. 简单实用jstl实现代码编写

    package com.ceshi; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.s ...

  8. Java生产者消费者模式

    为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能 ...

  9. 【bzoj2111】[ZJOI2010]Perm 排列计数 dp+Lucas定理

    题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Mogic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Mogic的,答案可能很 ...

  10. ActiveMQ使用经验与优化

    摘自:http://blog.csdn.net/m13321169565/article/details/8081314 1.1 不要频繁的建立和关闭连接 JMS使用长连接方式,一个程序,只要和JMS ...