RxJava只完成一个事件

时间:2018-01-16 12:14:42

标签: android rx-java2 rx-android rx-binding

我有一个带有Observable的登录屏幕,当电子邮件和密码有效时会发出项目,然后,我订阅启用或禁用登录按钮。
现在,我希望有一种方法可以避免在登录按钮中多次单击(避免多次调用webservice并在登录后打开多个活动)。

我曾尝试使用doOnNext()来禁用该按钮,但它与我的验证冲突(我最终无法启用按钮)

我的代码:

InitialValueObservable<CharSequence> emailChangeObservable = RxTextView.textChanges(binding.tietLoginLogin);
InitialValueObservable<CharSequence> passwordChangeObservable = RxTextView.textChanges(binding.tietLoginPassword);

Observable<Boolean> infoValidStream = Observable.combineLatest(emailChangeObservable, passwordChangeObservable, (email, password) -> {
            boolean validEmail = email.length() > 3 && email.toString().contains("@");
            boolean validPass = password.length() > 1;
            return validEmail && validPass;
        });

        infoValidStream.subscribe(validEmailAndPass -> binding.btLoginSignIn.setEnabled(validEmailAndPass));

        RxView.clicks(binding.btLoginSignIn)
              .subscribe(o -> login()); // do the request to the webservice and return a Single<User> if success.

我该如何实现这种行为?

2 个答案:

答案 0 :(得分:0)

您应该使用debouce方法。除非经过一段时间,否则它会使您的可观察物不会发出新物品。您可以根据需要设置此时间范围。

查看here以查看完整说明。

你可以用这种方式使用去抖动代码:

RxView.clicks(binding.btLoginSignIn)
              .debounce(400, TimeUnit.MILLISECONDS)
              .subscribe(o -> login());

这将避免用户在一秒钟内多次启动连接。

修改

但你也可以使用过滤器:

RxView.clicks(binding.btLoginSignIn)
              .filter { !connection.isActive() }
              .subscribe {login()};

它写在Kotlin,对不起我在Java中有点生锈,但那是逻辑。您需要一些方法来了解连接是否仍处于活动状态。

快乐的编码!

答案 1 :(得分:-2)

使用take运算符,例如

RxView.clicks(binding.btLoginSignIn)
      .take(1)
      .subscribe(o -> login());