65.9K
CodeProject 正在变化。 阅读更多。
Home

Android 绑定中的模型验证支持

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.25/5 (6投票s)

2011 年 1 月 14 日

GPL3

3分钟阅读

viewsIcon

50098

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 对象。整个模型也作为参数传入。

关于作者和项目

历史

  • 2011 年 1 月 14 日:初次发布
© . All rights reserved.