浅析RxJava处理复杂表单验证问题的方法

 更新时间:2016年06月13日 10:34:53   作者:soaringEveryday  
这篇文章主要介绍了RxJava处理复杂表单验证问题的相关资料,非常不错具有参考借鉴价值,需要的朋友可以参考下

无论是简单的登录页面,还是复杂的订单提交页面,表单的前端验证(比如登录名和密码都符合基本要求才能点亮登录按钮)都是必不可少的步骤。本文展示了如何用RxJava来方便的处理表单提交前的验证问题,例子采用了Android上的一个简单的登录页面

内容提要

传统的验证方式

combineLatest操作符

用combineLatest处理表单验证

combineLatest和zip的区别

本文中所演示的例子sample代码位于RxAndroidDemo,参见loginActivity这个文件

传统的验证方式

这里我们用最简单的例子来说明,如上图,一个email输入和一个password输入,下方是一个登录的按钮。只有当email输入框内容含有@字符,password输入框内容大于4个,才点亮下方的按钮。

首先你用EditText还是继承自EditText的控件,一般来说监听它的内容,都是用addTextChangedListener。但是如何显然登录按钮的enable与否是同时要判断email和password的,两个都成立才可点亮。所以我们在email的TextWatcher中除了要判断email是否符合条件以外,还要同时判断password是否符合条件,这样以来就容易造成多重判断。
试想如果你在提交一个订单的表单,上面是十几个输入框,每个输入的内容都同时符合条件才可以点亮“提交”按钮,这是多么痛苦的事情————每一个输入框的改变都要同时再判断其他十几个输入框内容是否符合(实际上此时其他十几个输入框没变化)

combineLatest操作符

combineLatest是RxJava本身提供的一个常用的操作符,它接受两个或以上的Observable和一个FuncX闭包。当传入的Observable中任意的一个发射数据时,combineLatest将每个Observable的最近值(Lastest)联合起来(combine)传给FuncX闭包进行处理。要点在于

1.combineLatest是会存储每个Observable的最近的值

2.任意一个Observable发射新值时都会触发操作->“combine all the Observable's lastest value together and send to Function”


用combineLatest处理表单验证

首先我们写上email和password的验证方法,一个需要含有@字符,一个要求字符数超过4个:

private boolean isEmailValid(String email) {
  //TODO: Replace this with your own logic
  return email.contains("@");
 }
private boolean isPasswordValid(String password) {
 //TODO: Replace this with your own logic
 return password.length() > 4;
}

随后,我们针对email和password分别创建Observable,发射的值即为各自edittext的变化的内容,而call回调方法的返回值是textWatcher中afterTextChanged方法的传入参数:

Observable<String> ObservableEmail = Observable.create(new Observable.OnSubscribe<String>() {
   @Override
   public void call(final Subscriber<? super String> subscriber) {
    mEmailView.addTextChangedListener(new TextWatcher() {
     @Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
     }
     @Override
     public void onTextChanged(CharSequence s, int start, int before, int count) {
     }
     @Override
     public void afterTextChanged(Editable s) {
      subscriber.onNext(s.toString());
     }
    });
   }
  });
Observable<String> ObservablePassword = Observable.create(new Observable.OnSubscribe<String>() {
 @Override
 public void call(final Subscriber<? super String> subscriber) {
  mPasswordView.addTextChangedListener(new TextWatcher() {
   @Override
   public void beforeTextChanged(CharSequence s, int start, int count, int after) {
   }
   @Override
   public void onTextChanged(CharSequence s, int start, int before, int count) {
   }
   @Override
   public void afterTextChanged(Editable s) {
    subscriber.onNext(s.toString());
   }
  });
 }
});

最后,用combineLastest将ObservableEmail和ObservablePassword联合起来进行验证:

Observable.combineLatest(ObservableEmail, ObservablePassword, new Func2<String, String, Boolean>() {
   @Override
   public Boolean call(String email, String password) {
    return isEmailValid(email) && isPasswordValid(password);
   }
  }).subscribe(new Subscriber<Boolean>() {
   @Override
   public void onCompleted() {
   }
   @Override
   public void onError(Throwable e) {
   }
   @Override
   public void onNext(Boolean verify) {
    if (verify) {
     mEmailSignInButton.setEnabled(true);
    } else {
     mEmailSignInButton.setEnabled(false);
    }
   }
  });

onNext中的verify就是经过combineLastest对两者验证后组合的结果。

参见LoginActivity的bindView()方法

这里,即使表单非常复杂,实际上你需要扩展的话就很容易了:

1.对每个EditText封装一个Observable

2.改写这句话,加入新的逻辑:

return isEmailValid(email) && isPasswordValid(password);

觉得为每一个EditText封装一个Observable要写很多重复代码?放心,Jake Wharton大神早已经想到,RxBinding中的RxTextView就可以解决这个问题:

Observable<CharSequence> ObservableEmail = RxTextView.textChanges(mEmailView);
Observable<CharSequence> ObservablePassword = RxTextView.textChanges(mPasswordView);
Observable.combineLatest(ObservableEmail, ObservablePassword, new Func2<CharSequence, CharSequence, Boolean>() {
 @Override
 public Boolean call(CharSequence email, CharSequence password) {
  return isEmailValid(email.toString()) && isPasswordValid(password.toString());
 }
}).subscribe(new Subscriber<Boolean>() {
 @Override
 public void onCompleted() {
 }
 @Override
 public void onError(Throwable e) {
 }
 @Override
 public void onNext(Boolean verify) {
  if (verify) {
   mEmailSignInButton.setEnabled(true);
  } else {
   mEmailSignInButton.setEnabled(false);
  }
 }
});

参见LoginActivity的bindViewByRxBinding()方法

combineLatest和zip的区别

zip是和combineLatest有点像的一个操作符,接受的参数也是两个或多个Observable和一个闭包。但是区别在于:

1.zip是严格按照顺序来组合每个Observable,比如ObservableA的第一个数据和ObservableB的第一个数据组合在一起发射给FuncX来处理,两者的第N个数据组合在一起发射给FuncX来处理,以此类推.

2.zip并不是任意一个Observable发射数据了就触发闭包处理,而是等待每个Observable的第N个数据都发射齐全了才触发

zip一般用于整合多方按照顺序排列的数据。


以上所述是小编给大家介绍的浅析RxJava处理复杂表单验证问题的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • java中Collections.sort排序函数用法详解

    java中Collections.sort排序函数用法详解

    本篇文章主要介绍了java中Collections.sort排序函数用法详解,非常具有实用价值,需要的朋友可以参考下。
    2016-12-12
  • Java利用InputStream类实现文件读取与处理

    Java利用InputStream类实现文件读取与处理

    在Java开发中,输入流(InputStream)是一个非常重要的概念,它涉及到文件读写、网络传输等多个方面,InputStream类是Java中输入流的抽象基类,定义了读取输入流数据的方法,本文将以InputStream类为切入点,介绍Java中的输入流概念及其应用,需要的朋友可以参考下
    2023-11-11
  • Java字段初始化的规律解析

    Java字段初始化的规律解析

    这篇文章主要介绍了Java字段初始化的规律解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • java 线程池的实现原理、优点与风险、以及4种线程池实现

    java 线程池的实现原理、优点与风险、以及4种线程池实现

    这篇文章主要介绍了java 线程池的实现原理、优点与风险、以及4种线程池实现包括了:配置线程池大小配置,线程池的实现原理等,需要的朋友可以参考下
    2023-02-02
  • Java实体类(entity)作用说明

    Java实体类(entity)作用说明

    这篇文章主要介绍了Java实体类(entity)作用说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Java链表超详细讲解(通俗易懂,含源码)

    Java链表超详细讲解(通俗易懂,含源码)

    链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的,下面这篇文章主要给大家介绍了关于Java链表超详细讲解的相关资料,本文讲解的内容通俗易懂,含源码,需要的朋友可以参考下
    2022-09-09
  • java排查一个线上死循环cpu暴涨的过程分析

    java排查一个线上死循环cpu暴涨的过程分析

    这篇文章主要介绍了java排查一个线上死循环cpu暴涨的过程分析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • 学习Java之如何正确地向上转型与向下转型

    学习Java之如何正确地向上转型与向下转型

    面向对象的第三个特征是多态,实现多态有三个必要条件:继承、方法重写和向上转型,在学习多态之前,我们还要先学习Java的类型转换,本篇文章就来带大家认识什么是类型转换,看看类型转换都有哪几种情况,以及如何避免类型转换时出现异常
    2023-05-05
  • Spring Boot开启的2种方式详解

    Spring Boot开启的2种方式详解

    这篇文章主要介绍了Spring Boot开启的2种方式详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • Java正则表达式的实例操作指南

    Java正则表达式的实例操作指南

    这篇文章主要给大家介绍了关于Java正则表达式的实例操作指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09

最新评论