StateFlowとDatabindingを試してみる

先日、Androud StudioのCanaryリリースでStateFlowがDataBindingに対応したので試してみました。

androidstudio.googleblog.com

今回確認したのは以下のみになります

  • StateFlowを使ってDataBindingが使えることを確認
  • MutableStateFlowを使って双方向DataBindingができることを確認

実際のソース

今回はViewModelを以下のように定義しました。

class MainViewModel : ViewModel() {
    val editTextFirst = MutableStateFlow("")
    val editTextSecond = MutableStateFlow("")
    private val first = editTextFirst.map { it.toFloatOrNull() }
    private val second = editTextSecond.map { it.toFloatOrNull() }
    private val result = first.combine(second) { a, b ->
        a ?: return@combine null
        b ?: return@combine null
        a * b
    }
    private val _text = MutableStateFlow("")
    val text = _text.asStateFlow()

    init {
        viewModelScope.launch {
            result.collect {
                _text.value = it.toString()
            }
        }
    }
}

(result: Flow から text: StateFlow に変換するまでのところをもうすこしうまく書きたい。。。

あとは、LiveDataを使うときと同じようにレイアウトファイルに設定してあげます。

        <TextView
            android:id="@+id/message"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="@{viewModel.text}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toTopOf="@id/edit_text_first"/>

        <EditText
            android:id="@+id/edit_text_first"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:inputType="numberDecimal"
            android:text="@={viewModel.editTextFirst}"
            app:layout_constraintTop_toBottomOf="@id/message"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toStartOf="@id/edit_text_second"/>

        <EditText
            android:id="@+id/edit_text_second"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:inputType="numberDecimal"
            android:text="@={viewModel.editTextSecond}"
            app:layout_constraintTop_toBottomOf="@id/message"
            app:layout_constraintStart_toEndOf="@id/edit_text_first"
            app:layout_constraintEnd_toEndOf="parent"/>

これによって、LiveDataと同じようにDataBindingできることが確認できました。