Observable.combine在kotlin中的最新类型推断

bli*_*ard 22 android kotlin rx-binding rx-java2

我在我的项目中使用RxJava2,Kotlin-1.1和RxBindings.

我有一个简单的登录界面,默认情况下禁用"登录"按钮,我想只在用户名和密码的edittext字段不为空时启用该按钮.

LoginActivity.java

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

我无法将上述代码从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() })
  }
}
Run Code Online (Sandbox Code Playgroud)

我假设它与第三个参数的类型推断有关combinelatest,但我没有通过阅读错误消息正确地解决问题: 类型推断问题

zsm*_*b13 38

您的问题是编译器无法确定combineLatest要调用的覆盖,因为多个覆盖都有功能接口作为其第三个参数.您可以使用SAM构造函数显式转换,如下所示:

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

PS.感谢您提出这个问题,它帮助我弄清楚我最初错误地认为这个问题是同样的问题,我现在也用这个解决方案更新了./sf/answers/2984555241/


tom*_*525 34

您可以使用RxKotlin为SAM模糊问题提供辅助方法.

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

如您所见,在RxKotlin中使用Observables而不是Observable