Observable.combineПоследний вывод типа в kotlin

Я использую 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, но я не понимаю проблему должным образом, прочитав сообщение об ошибке: Проблема определения типа


person blizzard    schedule 10.03.2017    source источник


Ответы (2)


Ваша проблема в том, что компилятор не может определить, какое переопределение combineLatest вызывать, потому что несколько из них имеют функциональные интерфейсы в качестве третьего параметра. Вы можете сделать преобразование явным с помощью конструктора SAM следующим образом:

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

Пс. Спасибо, что задали этот вопрос, это помогло мне понять, что я изначально ошибался в отношении этой проблемы, которая оказалась той же проблемой, которую я теперь также обновил с помощью этого решения. https://stackoverflow.com/a/42636503/4465208

person zsmb13    schedule 10.03.2017
comment
Мне потребовалось так много времени, чтобы понять это. - person Vicky; 09.12.2017
comment
Эта ссылка может быть полезна в связи с этим ответом. - person Francislainy Campos; 19.06.2019

Вы можете использовать RxKotlin, который дает вам вспомогательные методы для устранения неоднозначности SAM.

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

Как видите, в RxKotlin используйте Observables вместо Observable.

person tomoima525    schedule 05.11.2017
comment
Вы спасли мою жизнь! Спасибо. - person Johnny; 13.01.2018