Android控件状态依赖框架
在生产型Android客户端软件(企业级应用)开发中,界面可能存在多个输入(EditText)和多个操作(MotionEvent和KeyEvent),且操作依赖于输入的状态。如下图所示的场景:

设定图中
- 确认操作依赖于商品编码和储位的状态
- 跳过操作不依赖于输入状态
- 登记差异操作依赖于储位和数量的状态
输入框有三种状态:
- 待输入;
- 待校验;
- 校验成功。
操作需要当其依赖的输入数据校验成功,才能执行。
如果在Activity中去判断输入框状态,那么实际需要调用(3个输入框)*(3种状态)*(3个按钮) = 27个 if 判断,对于状态的维护将使得整个程序可维护性极差,并随着输入和操作的增加,维护的状态呈指数增长。
通过对这种场景的抽象,实现了Android控件状态依赖框架,其使用方法如下:
使用方法:
- 布局文件引用
WatchEditText和WatchButton
<com.android.yhthu.viewdependency.view.WatchEditText
android:id="@+id/edit_query_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="editQuery1"
android:imeOptions="actionNext"
android:hint="商品编码"
android:inputType="number"/>
<com.android.yhthu.viewdependency.view.WatchButton
android:id="@+id/search_button_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="buttonSearch1"
android:text="确认" />
由于
Library Module中的控件id不是常量(可参考ButterKnife对Library Module的支持采用R2的原因),这里采用了tag的方式。
- 在
Activity中通过注解申明依赖
@ViewName("商品编码")
private WatchEditText editQuery1;
@ViewName("储位")
private WatchEditText editQuery2;
@ViewName("数量")
private WatchEditText editQuery3;
@ViewDependency(name = @ViewName("确认"), dependency = {"editQuery1", "editQuery2"})
private WatchButton buttonSearch1;
@ViewDependency(name = @ViewName("跳过")/*不依赖输入*/)
private WatchButton buttonSearch2;
@ViewDependency(name = @ViewName("登记缺货"), dependency = {"editQuery2", "editQuery3"})
private WatchButton buttonSearch3;
ViewName定义控件名称,ViewDependency中dependency指定其依赖的控件tag。
3. 直接执行onClick和onEditorAction(修改状态)
@Override
public void onClick(View v) {
if (v == buttonSearch1) {
Toast.makeText(this, "调接口", Toast.LENGTH_SHORT).show();
} else if (v == buttonSearch2) {
Toast.makeText(this, "跳下一页", Toast.LENGTH_SHORT).show();
} else if (v == buttonSearch3) {
Toast.makeText(this, "登记缺货", Toast.LENGTH_SHORT).show();
}
}
可以看出,这里并没有通过if判断各个输入控件的状态。
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_NEXT && v == editQuery1
&& (query1Str = editQuery1.getText().toString()).isEmpty()) {
if (query1Str.equals("12345")) {
editQuery1.complete();
return true;
}
}
// 省略代码
return false;
}
onEditorAction模拟调用软件的Enter进行校验,这里需要注意通过editQuery1.complete()修改该EidtText的状态。
实现原理
整个框架分为三个package:annotation、state和view。
- 在
annotation中定义ViewName和ViewDependency注解,分别用于WatchEditText和WatchButton。ViewName指定WatchEditText控件在业务中的名称,ViewDependency指定WatchButton依赖的WatchEditText控件;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ViewDependency {
ViewName name() default @ViewName;
String[] dependency() default {};
}
- 在
state中通过状态模式定义Enter、Verify、Complete,其基类为抽象类Operator,定义方法operator;
public abstract class Operator {
// 操作对应的上下文
protected Context context;
// 操作
public abstract boolean operator(String operatorName, String viewName);
}
public class Enter extends Operator {
private static Enter enter;
private Enter(Context context) {
this.context = context;
}
public static Enter getInstance(Context context) {
if (enter == null) {
enter = new Enter(context);
}
return enter;
}
@Override
public boolean operator(String operatorName, String viewName) {
Toast.makeText(context, String.format("[%s]为空,不允许执行[%s]", viewName, operatorName),
Toast.LENGTH_SHORT).show();
return false;
}
}
WatchEditText和WatchButton定义控件的依赖关系。WatchEditText实现ViewState接口,其包含三种状态的转换方法。
public interface ViewState {
void enter();
void verify();
void complete();
}
以上,博客园对markdown支持的不太好,无法添加注释(/* */),如需查看源码,请移步Github地址:https://github.com/yhthu/AndroidViewDependency.git
Android控件状态依赖框架的更多相关文章
- Android Dagger依赖注入框架浅析
今天接触了Dagger这套android的依赖注入框架(DI框架).感觉跟Spring 的IOC差点儿相同吧.这个框架它的优点是它没有採用反射技术(Spring是用反射的),而是用预编译技术.因为基于 ...
- [Android]Android端ORM框架——RapidORM(v2.1)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6020412.html [Android]Android端ORM ...
- [Android]Android MVP&依赖注入&单元测试
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5422443.html Android MVP&依赖注入 ...
- 60.Android通用流行框架大全
转载:https://segmentfault.com/a/1190000005073746 Android通用流行框架大全 1. 缓存 名称 描述 DiskLruCache Java实现基于LRU的 ...
- Android的多媒体框架OpenCore介绍
网上资料很少, 不过还是找到一个比较详细的说明: 特地在此整理了下: 地址:http://blog.csdn.net/djy1992/article/details/9339787 分为几个阶段: 1 ...
- 【Android开发经验】来,咱们自己写一个Android的IOC框架!
到眼下位置.afinal开发框架也是用了好几个月了,还记得第一次使用凝视完毕控件的初始化和事件绑定的时候,当时的心情是多么的兴奋- -代码居然能够这样写!然后随着不断的学习,也慢慢的对IOC框架和注解 ...
- 从零开始搭建Android组件化框架
问题 在已经开发过几个项目的童鞋,如果这时需要重新开发一个新项目,是否需要自己重新搭建框架呢,还是从老项目中拷贝粘贴? 我们是否可以封装一个底层的lib库,这个底层的公共基础库 包括了一些第三方库(如 ...
- 支付宝客户端架构解析:Android 容器化框架初探
摘要: 本文将介绍支付宝 Android 容器化框架设计的基本思路. 1. 前言 由本章节开始,我们将从支付宝客户端的架构设计方案入手,细分拆解客户端在“容器化框架设计”.“网络优化”.“性能启动优化 ...
- 15类Android通用流行框架
15类Android通用流行框架 Android流行框架 缓存 DiskLruCache Java实现基于LRU的磁盘缓存 图片加载 Android Universal Image Loader 一个 ...
随机推荐
- Struts2 struts.xml配置
<?xml version="1.0" encoding="GBK"?> <!--指定 Struts2 的DTD信息 DTD 指 Docume ...
- javascript this的一些误解
太拘泥于"this"的字面意思就会产生一些误解.有两种常见的对于this 的解释,但是它们都是错误的. 1.指向自身 人们很容易把this 理解成指向函数自身,这个推断从英语的语法 ...
- Swift2.0 UITextView 和 UITextFile 的使用
在Swift2.0中,UITextFile 和 UITextView 的使用总体上和在OC中是一样的,今天只是给大家一段代码,然后说UITextView里面的光标位置的问题.先看他们使用的简单的代码 ...
- JavaSE学习笔记
1.数据类型 boolean char byte short int long double float double array class interface 总结: 前9种基本类型,后3中引用类 ...
- ubuntu通过虚拟域名访问不了 502 / 网络错误
##之前把虚拟机的lamp环境搭建好,但是通过自己windows在浏览器访问一直不能正常运行. 简单说明一下我的相关设置: 1.设置windows的ip映射 C:\Windows\System32\d ...
- ssh免密码和ssh-copy-id命令
Linux系统配置免密码的方式: 1:ssh-keygen -t rsa 生成密钥 2:ssh-copy-id -i ~/.ssh/id_rsa.pub 127.0.0.1 把本机的公钥追到jifen ...
- 浅谈css中一个元素如何在其父元素居中显示
css如何垂直居中一个元素的问题已经是一个老生常谈的问题了.不管对于一个新手或者老手,在面试过程中是经常被问到的.前两天在看一个flex的视频教程,当中提到了有关元素的居中问题,所以今天小编就来扒一扒 ...
- windows管道
匿名管道的使用 匿名管道主要用于本地父进程和子进程之间的通信, 在父进程中的话,首先是要创建一个匿名管道, 在创建匿名管道成功后,可以获取到对这个匿名管道的读写句柄, 然后父进程就可以向这个匿名管道中 ...
- C#开发step步骤条控件
现在很多的javascript控件,非常的不错,其中step就是一个,如下图所示: 那么如何用C#来实现一个step控件呢? 先定义一个StepEntity类来存储步骤条节点的信息: public c ...
- Filebeat issue 排查--single.go:140: ERR Connecting error publishing events (retrying): dial tcp ****:5044: i/o timeout
我个人用docker搭建了一套日志分析平台:ELK+Filebeat 在正常跑了半个多月之后,Kibana刷新日志时突然发现日志不在更新了,停在某个时刻,就再也没有新log. 首先我查看了elk,lo ...