Android 绑定中的模型验证支持
Android 绑定中 ViewModel 验证支持入门
引言
Android Binding 也支持通过 @Annotation 语法进行模型验证。您还可以通过几个简单的步骤添加自定义验证规则。以下文章基于市场上的示例应用程序。
或者搜索
- Android Binding 在应用市场
请下载示例应用程序,感受一下它的工作原理。源代码也可用。查看源代码页面 -> Demos 文件夹。
这就是示例的样子

上面显示了验证结果,以及自定义错误消息。本文将解释这一点。
关于 Android Binding

Android Binding 是一个支持声明式视图模型绑定的框架。您可以阅读此内容以获取更多信息。
初始视图模型
让我们从一个简单的注册视图模型开始
public class RegistrationViewModel{
public final Observable<CharSequence> Login;
public final Observable<CharSequence> Password;
public final Observable<CharSequence> ConfirmPassword;
public final Comamnd Submit;
}
请记住,在 Android Binding 中,希望 Observables 是公共字段,最好将其装饰为final,这样就不会发生后续的重新映射。
添加验证规则
好的,登录名和密码显然是强制性的。在 Android Binding 中,这被称为 *Required*。所有验证类都位于包中
com.gueei.android.binding.validation.validators;
请记住,如果您发现验证器不够用,您可以随时制作一个自定义的验证器,我们将在后面的文章中介绍。
因此,以下是我们如何指示 Android Binding 这些字段是必需的
public class RegistrationViewModel{
@Required
public final Observable<CharSequence> Login;
@Required
public final Observable<CharSequence> Password;
@Required
public final Observable<CharSequence> ConfirmPassword;
}
就是这样!我们只需要在必需的字段上放置一个 *@Required* 注解属性。
Validate
验证是通过调用static
方法完成的
ModelValidator.validate(model);
您可能希望在用户“提交”表单时进行验证。上面的代码行将返回一个 *ValidationResult* 类的对象,其中包含验证是否成功,如果不成功,则包含与之关联的错误消息。如果您不喜欢(是的,您不应该)预定义的消息,您可以放入自己的消息
...
@Required(ErrorMessage="You must put the login name!")
public final Observable<CharSequence> Login;
...
更多验证规则
确认密码是您想要确保用户没有错误输入密码的内容。它必须与密码字段相同。以下是我们如何做到这一点
@Required
@EqualsTo(Observable="Password")
public final Observable<CharSequence> ConfirmPassword;
简单!我们告诉框架,确认密码必须equalsto
另一个observable
,即密码字段。还有一件事,属性是“可堆叠的”,这意味着一个Observable
属性可以应用多个验证规则。就像上面的例子一样,这意味着
ConfirmPassword 是必需的,并且必须等于 Password
好的,我们已经完成了密码,用户名怎么样?我们只想接受字母、数字和下划线;并且必须至少 3 个字符到最多 8 个字符。检查所有类似内容的最简单方法是使用正则表达式。
@Required(ErrorMessage="You must put the login name!")
@RegexMatch(Pattern="^[A-Za-z0-9_]{3,8}$")
public final Observable<CharSequence> Login;
自定义验证
由于 Java 不支持 @interface
上的继承,因此使用自定义验证有点棘手。为了简化说明,我将从 @Required
注解的实现开始
@Retention(RetentionPolicy.RUNTIME)
public @interface Required{
public Class<?> Validator() default RequiredValidator.class;
public String ErrorMessage() default "%fieldname% is a required field";
public class RequiredValidator extends ValidatorBase<Required> {
@Override
public Class getAcceptedAnnotation() {
return Required.class;
}
@Override
protected String doFormatErrorMessage(Required parameters,
String fieldName) {
return parameters.ErrorMessage().replace("%fieldname%", fieldName);
}
@Override
protected boolean doValidate(Object value, Required parameters,
Object model) {
if (value==null) return false;
if (Boolean.FALSE.equals(value)) return false;
if (value instanceof CharSequence){
if (((CharSequence) value).length() == 0) return false;
}
return true;
}
}
}
我们必须将接口的保留声明为 @Retention(RetentionPolicy.RUNTIME)
,否则该属性在运行时将不可用。
字段 public Class<?> Validator()
是必须的,ModelValidator
仅适用于具有此字段的注解。它需要返回一个类,默认情况下,并且不应更改,这将是 Validator
类。
接口中的其他所有内容都是可选的,然后它们将作为“参数”(或选项)传递给验证器。
public class RequiredValidator extends ValidatorBase<Required>
声明验证器,它必须是 ValidatorBase<?>
的子类,其中 <?>
您应该放入您接受的 @interface
。
需要实现三个方法
getAcceptedAnnotation()
返回此验证器接受的@interface
的类型。doFormatErrorMessage()
返回格式化的错误消息,建议在各自的@interface
中定义备用错误消息,尽管这不是必须的。doValidate()
实际验证输入值。在这里,请注意第一个参数 *Object value* 是值,但不是 observable 对象。整个模型也作为参数传入。
关于作者和项目
- Andy Tsui
- 博客:http://andytsui.wordpress.com
- 项目讨论:http://groups.google.com/group/androidbinding
- 项目托管:http://code.google.com/p/android-binding/
历史
- 2011 年 1 月 14 日:初次发布