#52 AndroidでToDoアプリを作る - ViewModel
今回はToDoアプリにJetpackのViewModelを導入してみます。
ViewModelとは
ViewModelとはJetpackで提供されているライブラリで、2017年にアーキテクチャコンポーネントとして登場しました。ライフサイクルを意識した方法でUI関連のデータを保存・管理するために使います。
画面回転
ViewModelを使う理由の1つに画面回転があります。通常、画面回転が発生するとメモリ上のアクティビティやフラグメントオブジェクトは一旦破棄され、再生成が行われます。これにより、次の2つの問題が生じます。
- UI関連のデータが消失してしまう
- 実行中の非同期処理をとめる必要がある
ViewModelは画面回転が発生しても破棄されないので、UI関連のデータは消失せず、非同期処理もそのまま実行しつづけることができます。
ライブラリを追加する
ViewModel自体はappcompatライブラリの依存関係として追加されているので、明示的にライブラリを追加せずに使えます。ActivityやFragmentでViewModelを扱うための拡張関数がktxとして用意されているので、次のライブラリを追加します。
dependencies {
implementation 'androidx.fragment:fragment-ktx:1.3.0-beta02'
}
また、fragment-ktxがJava 8の機能を使用するため、app/build.gradleに次のセクションを追加します。
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
各画面用のViewModelを作る
次に、各画面用のViewModelを作ります。ViewModelを継承したクラスを作ります。中身は各画面の詳細を作るときに作るので、空っぽで構いません。
package com.mokelab.mytodo
class MainViewModel: ViewModel() {
}
同様に、各画面用のViewModelも作っていきます。
package com.mokelab.mytodo.page.create
class CreateToDoViewModel: ViewModel() {
}
package com.mokelab.mytodo.page.detail
class ToDoDetailViewModel: ViewModel() {
}
package com.mokelab.mytodo.page.edit
class EditToDoViewModel: ViewModel() {
}
プロパティとしてViewModelをもたせる
最後に、各フラグメントにViewModelをプロパティとしてもたせます。KotlinのDelegated
Propertyの仕組みを使います。by viewModels()
は、fragment-ktxで定義されている拡張関数です。
package com.mokelab.mytodo
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
class MainFragment: Fragment(R.layout.main_fragment) {
private val vm: MainViewModel by viewModels()
}
他の画面も同様にプロパティとして追加していきます(import文は省略します)。
package com.mokelab.mytodo.page.create
class CreateToDoFragment: Fragment(R.layout.create_todo_fragment) {
private val vm: CreateToDoViewModel by viewModels()
}
package com.mokelab.mytodo.page.detail
class ToDoDetailFragment: Fragment(R.layout.todo_detail_fragment) {
private val vm: ToDoDetailViewModel by viewModels()
}
package com.mokelab.mytodo.page.edit
class EditToDoFragment: Fragment(R.layout.edit_todo_fragment) {
private val vm: EditToDoViewModel by viewModels()
}
これで、各画面にViewModelを追加することができました。
まとめ
今回はViewModelを作成し、各画面に追加してみました。ViewModelの中身をどのように書いていくかは、後の回で詳しく説明します。