web-dev-qa-db-ja.com

KotlinのObservable.combineLatest型推論

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の3番目の引数の型推論に関連するものだと思いましたが、エラーメッセージを読んで問題を適切に取得できません: Type Inference issue

21
blizzard

あなたの問題は、combineLatestのどのオーバーライドを呼び出すかをコンパイラが判断できないことです。これは、複数のパラメーターが3番目のパラメーターとして機能的なインターフェースを持っているためです。次のようなSAMコンストラクタを使用して、変換を明示的に行うことができます。

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

追伸この質問をしてくれてありがとう、それは同じ問題であることが判明したこの問題について最初は間違っていたことを理解するのに役立ちました。 https://stackoverflow.com/a/42636503/4465208

37
zsmb13

RxKotlin を使用できます。これにより、SAMの曖昧さの問題に対するヘルパーメソッドが提供されます。

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

ご覧のとおり、RxKotlinではObservablesの代わりにObservableを使用します

31
tomoima525