RxJava操作符 debounce 和 distinctUntilChanged

54 篇文章 0 订阅


1 debounce操作符是用来防重复数据的或者(防抖动):

public final Observable<T> debounce(long timeout, TimeUnit unit) {
        return debounce(timeout, unit, Schedulers.computation());
    }
可以看出只需要传入防抖时间就可以了,比如debounce(200, TimeUnit.MILLISECONDS)就代表如果释放的数据间隔上一次释放数据在200毫秒内则丢弃这一次释放,即不会引发onnext的执行。


2 distinctUntilChanged操作符顾名思义,只有当我们观察的数据状态发生改变的时候才会释放数据,而对于状态的定义可以使用默认也可以自己定义,默认情况下就是对前后两次数据进行比较,如果key相等则此次不释放,如果不相等则释放:

U currentKey = previousKey;
                U key = keySelector.call(t);
                previousKey = key;
                
                if (hasPrevious) {
                    if (!(currentKey == key || (key != null && key.equals(currentKey)))) {
                        child.onNext(t);
                    } else {
                        request(1);
                    }
                } else {
                    hasPrevious = true;
                    child.onNext(t);
                }
需要注意的是,它只会对前后两次释放的数据进行比较。



那么了解了上面两个操作符,就可以知道注册页面是很适合它们的场景,特别是当所有输入框输入的数据满足一定的条件时才会使提交按钮变亮,一旦不满足则会变暗。代码如下:

private void combineListener() {
    subscription.add(Observable.combineLatest(phoneViewObservable, passwordViewObservable,
        new Func2<Boolean, Boolean, Boolean>() {
          @Override public Boolean call(Boolean phoneEnable, Boolean passwordEnable) {
            return phoneEnable && passwordEnable;
          }
        }).distinctUntilChanged().subscribe(inputChangeSubscriber()));
  }

  private void bindListenerToPhoneChange() {
    phoneViewObservable = RxTextView.textChangeEvents(phoneView)
        .debounce(DEBOUNCE_MILLISECONDS, TimeUnit.MILLISECONDS)
        .map(new Func1<TextViewTextChangeEvent, Boolean>() {
          /**
           * phone text validation
           */
          @Override public Boolean call(TextViewTextChangeEvent textViewTextChangeEvent) {
            return !TextUtils.isEmpty(textViewTextChangeEvent.text().toString());
          }
        })
        .observeOn(AndroidSchedulers.mainThread());
  }

  private void bindListenerToPasswordChange() {
    passwordViewObservable = RxTextView.textChangeEvents(passwordView)
        .debounce(DEBOUNCE_MILLISECONDS, TimeUnit.MILLISECONDS)
        .map(new Func1<TextViewTextChangeEvent, Boolean>() {
          /**
           * password text validation
           */
          @Override public Boolean call(TextViewTextChangeEvent textViewTextChangeEvent) {
            return !TextUtils.isEmpty(textViewTextChangeEvent.text().toString());
          }
        })
        .observeOn(AndroidSchedulers.mainThread());
  }

  /**
   * toggle target view when emitted
   */
  private Observer<Boolean> inputChangeSubscriber() {
    return new EndSubscriber<Boolean>() {
      @Override public void onNext(Boolean enable) {
        toggleSubmitBackground(enable);
      }

      @Override public void onEnd() {

      }
    };
  }

debounce防止了快速输入,distinctUntilChanged用于防止重复执行得到相同结果。当然这里使用了rxbinding。如果有多个输入框,只需要在combinelatest里面加上就可以了,需要注意的是如果需要对输入结果和其他单一变量变化(比如是否同意注册协议变量)的混合验证时,可能会在变量变化时进行手动触发工作流,因为所有需要验证的流程都需要走distinctUntilChanged这个节点,如果不走这个节点那么当单一变量有变化就不会被记录为上一次释放数据,因而可能会把正确的数据校验释放丢弃掉。手动触发可以使用PublishSubject。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值