android - rxkotlin - Observable.combineLatest type inference en kotlin
rxkotlin android tutorial (2)
Estoy usando RxJava2, Kotlin-1.1 junto con RxBindings en mi proyecto.
Tengo una pantalla de inicio de sesión simple con el botón "iniciar sesión" desactivado de forma predeterminada. Quiero habilitar el botón solo cuando los campos de nombre de usuario y contraseña no estén vacíos.
LoginActivity.java
Observable<Boolean> isFormEnabled =
Observable.combineLatest(mUserNameObservable, mPasswordObservable,
(userName, password) -> userName.length() > 0 && password.length() > 0)
.distinctUntilChanged();
No puedo traducir el código anterior de Java a 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() })
}
}
Supuse que es algo relacionado con la inferencia de tipo del tercer argumento en combinelatest
, pero no entiendo el problema correctamente al leer el mensaje de error:
Puede usar RxKotlin que le brinda métodos de ayuda para el problema de ambigüedad SAM.
val isSignInEnabled: Observable<Boolean> = Observables.combineLatest(
userNameObservable,
passwordObservable)
{ u, p -> u.isNotEmpty() && p.isNotEmpty() })
Como puede ver, en RxKotlin use Observables
lugar de Observable
Su problema es que el compilador no puede averiguar qué anulación de combineLatest
llamar, porque varias interfaces tienen interfaces funcionales como su tercer parámetro. Puedes hacer la conversión explícita con un constructor de SAM como este:
val isSignInEnabled: Observable<Boolean> = Observable.combineLatest(
userNameObservable,
passwordObservable,
BiFunction { u, p -> u.isNotEmpty() && p.isNotEmpty() })
PD. Gracias por hacer esta pregunta, me ayudó a darme cuenta de que inicialmente estaba equivocada con respecto a este problema que resultó ser el mismo, que ahora también he actualizado con esta solución. https://.com/a/42636503/4465208