You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

RxJava实现登录按钮仅响应一次点击:避免重复请求与页面跳转

解决登录按钮重复点击问题(兼容原有验证逻辑)

我来帮你搞定这个问题!你的核心需求很明确:既要保留原有的邮箱+密码验证逻辑来控制登录按钮的启用状态,又要避免用户在登录请求过程中重复点击按钮(防止多次调用接口或打开多个页面)。之前用doOnNext()直接禁用按钮导致和验证逻辑冲突,是因为这种方式直接覆盖了验证流对按钮状态的控制,我们换一种更优雅的方式来实现。

核心思路

我们需要把验证通过状态登录请求中状态结合起来,共同决定按钮是否可点击:

  • 只有当验证通过 没有正在进行的登录请求时,按钮才是可点击的
  • 一旦用户点击按钮发起登录,立刻标记“登录中”状态,禁用按钮
  • 不管登录成功还是失败,登录请求结束后都要取消“登录中”标记,让按钮回到验证逻辑控制的状态

完整代码实现

// 1. 原有的输入变化监听和验证逻辑保持不变
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;
});

// 2. 创建一个BehaviorSubject来跟踪登录请求的状态(默认是未登录状态)
BehaviorSubject<Boolean> loginInProgress = BehaviorSubject.createDefault(false);

// 3. 合并验证状态和登录中状态,共同控制按钮的启用
Observable.combineLatest(infoValidStream, loginInProgress, (isValid, isLoading) -> {
    // 只有验证通过且不在登录中,按钮才可用
    return isValid && !isLoading;
}).subscribe(canLogin -> binding.btLoginSignIn.setEnabled(canLogin));

// 4. 处理按钮点击事件,同时控制登录状态
RxView.clicks(binding.btLoginSignIn)
    .flatMapSingle(o -> {
        // 标记为登录中,触发按钮禁用
        loginInProgress.onNext(true);
        // 发起登录请求,同时在请求结束后(无论成功/失败)取消登录中标记
        return login()
            .doFinally(() -> loginInProgress.onNext(false));
    })
    .subscribe(
        user -> {
            // 登录成功后的逻辑:比如跳转主页面
        },
        error -> {
            // 登录失败后的逻辑:比如提示错误信息
        }
    );

代码解释

  • BehaviorSubject<Boolean> loginInProgress:用来实时发布当前是否正在登录的状态,默认是false(未登录)
  • combineLatest合并两个流:把原有的验证通过状态和登录中状态结合,确保只有在验证通过且没有登录请求时,按钮才会被启用
  • flatMapSingle+doFinally:点击按钮后立刻标记登录中,发起登录请求,不管请求成功还是失败,doFinally都会在请求结束时将登录状态改回未登录,让按钮恢复到验证逻辑控制的状态

这种方式完全不会破坏你原有的验证逻辑,同时完美解决了重复点击的问题,而且不管登录成功失败都能正确恢复按钮状态~

内容的提问来源于stack exchange,提问作者reinaldo

火山引擎 最新活动