Mokelab Blog

#52 AndroidでToDoアプリを作る - ViewModel

今回はToDoアプリにJetpackのViewModelを導入してみます。

ViewModelとは

ViewModelとはJetpackで提供されているライブラリで、2017年にアーキテクチャコンポーネントとして登場しました。ライフサイクルを意識した方法でUI関連のデータを保存・管理するために使います。

画面回転

ViewModelを使う理由の1つに画面回転があります。通常、画面回転が発生するとメモリ上のアクティビティやフラグメントオブジェクトは一旦破棄され、再生成が行われます。これにより、次の2つの問題が生じます。

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の中身をどのように書いていくかは、後の回で詳しく説明します。

本サイトではサービス向上のため、Google Analyticsを導入しています。分析にはCookieを利用しています。