在Kotlin中,Observable.combineLatest类型推断

26

我在我的项目中使用RxJava2,Kotlin-1.1以及RxBindings。

我有一个简单的登录界面,默认情况下'登录'按钮是禁用的,我希望只有当用户名和密码的编辑文本字段不为空时才启用该按钮。

LoginActivity.java

Observable<Boolean> isFormEnabled =
    Observable.combineLatest(mUserNameObservable, mPasswordObservable,
        (userName, password) -> userName.length() > 0 && password.length() > 0)
        .distinctUntilChanged();

我无法将上述Java代码翻译成Kotlin:

LoginActivity.kt

class LoginActivity : AppCompatActivity() {

  val disposable = CompositeDisposable()

  private var userNameObservable: Observable<CharSequence>? = null
  private var passwordObservable: Observable<CharSequence>? = null

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_login)
    initialize()
  }

  fun initialize() {
    userNameObservable = RxTextView.textChanges(username).skip(1)
        .debounce(500, TimeUnit.MILLISECONDS)
    passwordObservable = RxTextView.textChanges(password).skip(1)
        .debounce(500, TimeUnit.MILLISECONDS) 
  }

  private fun setSignInButtonEnableListener() {
    val isSignInEnabled: Observable<Boolean> = Observable.combineLatest(userNameObservable,
        passwordObservable,
        { u: CharSequence, p: CharSequence -> u.isNotEmpty() && p.isNotEmpty() })
  }
}
我觉得这可能与combinelatest的第三个参数的类型推断有关,但是通过阅读错误消息,我没有完全理解这个问题: Type Inference issue
2个回答

43

你的问题在于编译器无法确定调用哪个combineLatest的重载函数,因为有多个具有功能接口作为第三个参数。你可以使用SAM构造函数显式地进行转换,如下所示:

val isSignInEnabled: Observable<Boolean> = Observable.combineLatest(
        userNameObservable,
        passwordObservable,
        BiFunction { u, p -> u.isNotEmpty() && p.isNotEmpty() })

顺便说一下,感谢提出这个问题,它帮助我弄清楚了我最初对这个问题的错误看法,事实证明这是同样的问题,我已经用这个解决方案进行更新了。 https://dev59.com/_lgQ5IYBdhLWcg3whERn#42636503


我花了很长时间才弄明白这个。 - Vicky
这个链接可能与这个答案有关。 - Francislainy Campos

40

您可以使用RxKotlin,它为SAM歧义问题提供了辅助方法。

val isSignInEnabled: Observable<Boolean> = Observables.combineLatest(
    userNameObservable,
    passwordObservable)
    { u, p -> u.isNotEmpty() && p.isNotEmpty() })

正如您所看到的,在 RxKotlin 中使用 Observables 而不是 Observable


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接