MediatorLiveDataとTransformation
Mediator LiveDataとは
各種LiveDataとViewの仲介役をつとめてくれるライブデータです。
例えば、ゲームを作っていてアイテムA、アイテムBのいずれかの所持数が10を切ると危険の表示が出るような状況を考えてみましょう。 このような状況で解決策の一つとしてItemAの所持数が変化したことを伝えるLivedataを作り、同様のものをItemBについても作成すると考えてみましょう。 各データをView(ActivityやFragmant)で監視することによって、表示を切り替えることが可能です。
Solution 1
val itemACount:MutableLiveData<Int>=MutableLiveData() val itemBCount:MutableLiveData<Int>=MutableLiveData()
使用側では
itemACount.observe{this,Obsrver{Toast.makeText(this,"Item Is Not Full",Toast.LONG_LENGTH).show()}} //簡単のためToastにしています。 itemBCount.observe{this,Obsrver{Toast.makeText(this,"Item Is Not Full",Toast.LONG_LENGTH).show()}}
可能ではありますが、すべてのデータに対してObserveを呼ぶのは少し面倒です。
そこで今回の紹介するMediatorLiveDataを使用することにより、複数のLiveDataがあたかも一つであるかのように扱うことができます。
Solution 2
val itemACount:MutableLiveData<Int>=MutableLiveData() val itemBCount:MutableLiveData<Int>=MutableLiveData() val mediator=MediatorLiveData<Int>().apply{ addSource(itemACount) {this.value=it} addSource(itemBCount) {this.value=it} } val itemIsNotFull: LiveData<Boolean> =Transformations.map(mediator) { if (it=<10) return@map true else false }
MediatorLiveDataは単にまとめる役割のみをもっています、そこでMediator自身にAddSource内で値をセットします。
使う側では通常通りに
itemIsNotFull.observe{this,Obsrver{Toast.makeText(this,"Is Not Full",Toast.LONG_LENGTH).show()}}
と行えば、ItemA ItemBのどれかが10以下になったときにLiveDataに通知してくれます。
一行でまとめられるので楽です。
雑(な)感(想)
公式の方法に沿ってTransformations を使用したんだけど、Mediator LiveData 内部で変換しちゃだめなのかな? 多分拡張性の観点から(例えば10以下じゃなくて5以下とかを追加したくなったときに困るから)そうしてるんだろうね