🍣
MutableLiveData は双方向データバインディングにも使える
データバインディングを利用して EditText に入力した内容を ViewModel に通知する処理を実装していました。
<EditText
android:id="@+id/form_user_name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{viewmodel.userName}" />
FormViewModel.kt
class FormViewModel : ViewModel() {
var userName = ObservableField<String>()
}
上記の実装だと、FormViewModel
からuserName
を変更すると View に反映されますが、逆に画面からテキストを入力してもFormViewModel
のuserName
に反映されません。
つまり、ViewModel -> View は対応しているが、View -> ViewModel には対応していません。
双方向データバインディング
上記の問題を解決するためには、「双方向データバインディング」にする必要があります。
名前の通り、ViewModel -> View だけでなく、View -> ViewModel にも対応するための仕組みです。
対応方法
それぞれ以下のように変更します。
<EditText
android:id="@+id/form_user_name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={viewmodel.userName}" />
xml の方は@
と{
の間に=
を追加するだけです。
FormViewModel.kt
class FormViewModel : ViewModel() {
val userName = MutableLiveData<String>()
}
ViewModel の方はFormViewModel
のuserName
をMutableLiveData<String>
に変更するだけです。
また、MutableLiveData を使わない、従来型の方法(公式サイト記載)もあります。
FormViewModel.kt
import com.example.simplemvvmapp.BR
class FormViewModel : BaseObservable() {
@Bindable
var userName: String = ""
set(value) {
field = value
notifyPropertyChanged(BR.userName)
}
}
ですが MutableLiveData を使う方が簡単に書けますし、ライフサイクルにも考慮してくれるので、MutableLiveData を使うことをお勧めします。
まとめ
MutableLiveData は双方向データバインディングにも使えるということがわかりました。
普通にデータバインディング以外にも使えるのでもっと積極的に使っていきたいです。
Discussion