Android|Android Form组件
场景
Android APP里面时常有于登录、注册、信息填写提交等页面,业务逻辑差不多都是用户输入或者选择某些信息,然后点击提交,客户端这边依次判断用户名是否为空,长度是否在某个范围内等等,如果某一个不符合要求,就提示相应信息,如果都符合,就组合成key=value形式发起请求。
引申
上述场景类似于HTML里面的form标签
复制代码
在Android里面,登录、注册这些页面是否也像一个个form呢,我们能否也用一个配置文件配置请求的URL,请求方式,然后配置相关的控件,最后在点击提交按钮时自动组装?
【Android|Android Form组件】再引申一步,登录页面里面,我们需要判断用户名为空、长度、匹配规则等,密码为空、长度、匹配规则等,然后分别给提示。在信息填写页面就更多了,有可能需要用户输入好几十条的信息分别判断,这样就导致了代码冗余和重复。能否在配置里面就配置好相应的检查规则,在点击提交的时候自动依次检查?
答案是可以的~下面就来看看例子
示例布局
复制代码
为了简单快捷,都是用的LinearLayout,这样影响性能,这里当一个反面教材吧。。。
常规写法
- 先findByID,获取全部的控件。
- 按钮设置监听。
- 按钮点击之后依次判断:性别是否选择?没有就提示;账号是否为空?长度是否是11位?没有分别弹提示;密码是否为空?长度是否大于6?长度是否小于16?没有分别弹提示;协议编号是否为空?是否都是字母?没有弹提示。
- 如果还有其他信息,依次增加同样的逻辑。
json配置
{
"action":"https://www.xxx.com",
"method":"post",
"item":[
{
"id":"rg_sex",
"rules":{
"notNull":[true, "性别不能为空"]
},
"paramName":"sex"
},
{
"id":"et_user",
"rules":{
"notNull":[true, "账号不能为空"],
"length":[11, "账号长度必须是11位"]
},
"paramName":"userName"
},
{
"id":"et_password",
"rules":{
"notNull":[true, "密码不能为空"],
"minLength":[6, "密码最短为6位"],
"maxLength":[16, "密码最长为16位"]
},
"paramName":"userPwd"
},
{
"id":"diy_view",
"rules":{
"notNull":[true, "协议编号不能为空"],
"textMatch":["[a-zA-Z]+", "协议编号需要全部为字母"]
},
"paramName":"protocol"
},
{
"id":"btn_login",
"type":"submit"
}
]
}
复制代码
action:提交的URL
method:提交的方式
item:Form里面的控件,比如选择按钮、文本框和提交按钮等。
id:控件定义的id,使用反射获取控件。
rules:检测规则,比如不为空、长度检查等。点击提交时会按照里面配置的规则依次检查。
paramName:点击提交时,对应的key。value就是控件里面的内容。
type代表控件类型,无此字段时,则默认需要获取该控件内容上传,如果为“submit”,则表示是个提交按钮,当点击该按钮时,会逐个检查其他字段是否匹配规则,如果都通过了,则会组装全部参数返回。
程序代码
// 自定义View,里面绘制了文字
DIYView diyView = findViewById(R.id.diy_view);
diyView.setText("abxcSDDFsdcAd");
// 自定义规则,名称是“textmatch”,类名是RuleTextMatch.java
Form.addRule("textMatch", RuleTextMatch.class);
// 自定义检查的View,用于检查DIYView等其他View的输入,可通过instanceof判断类型之后获取相应内容
Form.setCheckView(DIYCheckView.class);
String jsonStr = FileUtil.parseAssetsFile(this, "config/testConfig01.json");
Form form = new Form();
form.parseView(view, jsonStr);
form.setFormCommitListener(new OnFormCommitListener() {
@Override
public void onFormCommitChecked(Form form, String method, String url, Map paramMap) {
Toast.makeText(MainActivity.this, "method=" + method + "\nurl=" + url + "\n" + "paramMap=" + paramMap.toString(), Toast.LENGTH_SHORT).show();
}@Override
public void onFormCommitError(Form form, ICheckItem checkItem, IRule errorRule) {
Toast.makeText(MainActivity.this, errorRule.getErrorMsg(), Toast.LENGTH_SHORT).show();
}
});
复制代码
说明 由于json配置文件里面写明了id,所以库里面就自动findViewByID了,外部调用省去了该过程。rules写明了判断规则,第一个参数是条件,第二个参数默认是未符合的情况下的提示,当然,这个在实现了IRule接口之后可以自己定义参数的顺序和含义。rules里面的顺序决定了程序判断的顺序。
扩展
扩展规则 例如扩展一个正则匹配的规则,名称是“textMatch”。
- 新建一个类RuleTextMatch继承AbsRule,或者实现IRule接口。
public class RuleTextMatch extends AbsRule {private String matchFormatStr = null;
@Override
public void setParam(List
- 注册该规则
//在程序启动的时候就可以注册了,使用Form的静态方法addRule
Form.addRule("textMatch", RuleTextMatch.class);
复制代码
- json配置
{
"id":"diy_view",
"rules":{
"notNull":[true, "协议编号不能为空"],
"textMatch":["[a-zA-Z]+", "协议编号需要全部为字母"]
},
"paramName":"protocol"
}
复制代码
扩展View 目前阶段只支持RadioGroup和TextView(EditText, Button等继承了TextView),如果想扩展其他的View,只需要创建一个类继承CheckView或者实现ICheckItem接口即可。 例如我们自定义了一个DIYView。
- DIYView
public class DIYView extends View {
// ...省略其他方法
private String text;
public String getText() {
return text;
}
// ...省略其他方法
}
复制代码
- 需要扩展一个类DIYCheckView,来解析DIYView和其他扩展的View。整个外部扩展解析类只需要这一个就可以了。
public class DIYCheckView extends CheckView {@Override
public String getCheckContent() {
String content = super.getCheckContent();
if (content != null) {
return content;
}
// 通过instanceof判断各个类型View的获取文本的方法。
if (view instanceof DIYView) {
return ((DIYView) view).getText();
}
return content;
}
}
复制代码
- 使用
// 在程序启动时,调用Form的静态方法setCheckView就可以了
Form.setCheckView(DIYCheckView.class);
复制代码
小结
- 文中的输入信息的就三四个,可能觉得自己写也挺快。但是如果需要用户填写详细信息好几十条的时候,每个都要判断一些乱七八糟的规则,这个就轻松多了。
- 由于加载的是配置文件,也就是说该文件是可以随时更新的,当某一个规则发生变化的时候可以及时更新,例如本地判断了用户名11位,后来需求更改不限制位数了,只需要更新配置文件即可。
- 由于是一个aar库,不用每次去编译,扩展的时候也不需要修改库里面的文件。
git链接:FormLike 转载于:https://juejin.im/post/5b56977df265da0f990d5c2e
推荐阅读
- android第三方框架(五)ButterKnife
- Android中的AES加密-下
- 带有Hilt的Android上的依赖注入
- android|android studio中ndk的使用
- Android事件传递源码分析
- RxJava|RxJava 在Android项目中的使用(一)
- Android7.0|Android7.0 第三方应用无法访问私有库
- 深入理解|深入理解 Android 9.0 Crash 机制(二)
- android防止连续点击的简单实现(kotlin)
- Android|Android install 多个设备时指定设备