【Kotlin/Android Studio】LiveDataの使い方!更新を監視してUIとデータの同期
この記事からわかること
- Android StudioのLiveDataを利用する方法
- 画面が再構築される際にデータを保持するには?
- ViewModelの変更を監視とは?
- MutableLiveDataとLiveDataの違い
- LifecycleOwnerとは?
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
参考文献:公式リファレンス:LiveData
環境
- Android Studio:Flamingo
- Kotlin:1.8.20
ViewModelで実装できたこと
上記の記事でViewModelを実装し画面を横向きにしてもデータが損なわれないようにできました。
しかし画面を一度横にした際にはUI上ではデータがリセットされてしまったかのように見えるのが欠点だったのでそこをLiveDataを利用して補っていきたいと思います。
LiveDataとは?
Androidアプリ開発のLiveDataはJetPackのコンポーネントの1つとして提供されているデータを監視できる機能です。LiveDataではライフサイクルに応じた監視が可能になっており、ActivityやFragment、ViewModelなどの監視がより鮮明に可能になります。
メリット
- UIとデータの状態の同期
- メモリリークが発生しない
- 停止されたアクティビティに起因するクラッシュが発生しない
- 手動によるライフサイクル処理が不要
- データが常に最新
- 適切な設定の変更
- リソースの共有
Androidではアプリの画面が縦型から横向きに変更になる際に画面が再構築されるという特徴があります。この際にデータやUI状態などが一度リセットされてしまうため同じ画面を表示することができない場合があります。これをViewModelでデータのキャッシュまではできているのでLiveDataを利用してUIに反映させていきたいと思います。
実装方法
最新のAndroid Studio:Flamingoであればプロジェクト内で使用するために必要な導入作業は必要ありません。またプロジェクトの全体はGitHubに上げていますので参考にしてください。
今回はViewModelで作成した「ボタンクリックで2つのカウンターが変化する」アプリを改修していきます。
ViewModelのプロパティをMutableLiveDataに変更
LiveDataを使用するためにはViewModelのプロパティをMutableLiveData
クラスとLiveData
クラスの2つに変更します。Mutableとは「可変」という意味で変更可能な構造と変更不可(immutable)な構造の2つを用意しています。これは外部からViewModelのデータを変更されないようにしているためです。
class MyViewModel:ViewModel() {
private val my_counter: MutableLiveData<Int> = MutableLiveData<Int>(0)
val count:LiveData<Int> = my_counter
fun plus(){
val counter = my_counter.value ?: throw Exception("Invalid _count value")
my_counter.value = counter + 1
}
}
これで監視するためのデータを定義することができました。
監視を開始
監視を開始するためには以下のように書き換えます。
button.setOnClickListener {
planeCounter++
vm.plus()
planeText.setText(planeCounter.toString())
}
val countObserver = Observer<Int> {it
vmText.text = it.toString()
}
vm.count.observe(this,countObserver)
まずObserver
でLiveDataの変更を監視し、変更があった場合に実行する関数を設定しています。
val countObserver = Observer<Int> {it
vmText.text = it.toString()
}
そしてobserve
メソッドで変更の監視を始めます。引数には監視の終了タイミングなどを依存するLifecycleOwner
を指定します。今回はActivityのためthis
で良いですがFragmentで使用する際はメモリリークが発生する可能性があるためviewLifecycleOwner
を使用してください。
vm.count.observe(this,countObserver)
これでアプリを横向きにしてもViewModel側のみデータが損なわれることはなくなりました。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。