くま's Tech系Blog

基本的には技術で学んだことを書き留めようと思います。雑談もやるかもね!

レッツMVVMパターン

以前、DataBindingを使ってみて、その延長でMVVMパターンを使ってみました。

おそらく今後も使うと思うので、手順を残したいと思います。

ベースは下記の記事の実装を使います。

DataBindingを使ってみる

今回はListViewで行います。 ModelViewは 一覧に表示するデータのリストを保持して、Adapterに適用させます。 そのAdapterをListViewに適用させるイメージです。

①ライブラリの追加

ModelViewを使うために、ライブラリを追加します。

dependencies {
    // 追加
    implementation 'android.arch.lifecycle:extensions:1.1.1'
}

②ModelViewの作成

次にModelViewを作成します。 ModelViewではデータのリスト(画面に表示させるもの)を保持します。

class ListViewModel: ViewModel() {

    private lateinit var realm: Realm

    fun loadData(): List<TaskDetail> {
        realm = Realm.getDefaultInstance()
        val tasks = realm.where<Task>().findAll().sort("id")
        val taskList = mutableListOf<TaskDetail>()

        // タスク一覧に表示するタイトルと期限をリスト化
        tasks.forEach { taskList.add(TaskDetail(it.title,
                DateFormat.format("yyyy/MM/dd", it.date).toString() + "  " + DateFormat.format("HH:mm", it.time).toString(), it.id)) }

        return taskList
    }
}

③Activityの修正

Activityを修正します。 今まではActivityでデータを取得して、Adapterと紐づけを行っていましたが、

今回はModelViewで定義したデータを取得する関数を呼び出し、Adapterと紐づけするだけなので、かなりコード量が減りました。

class MainActivity : AppCompatActivity() {
    private lateinit var realm: Realm

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)
        realm = Realm.getDefaultInstance()
        val binding : ActivityMainBinding

        // MainActivityをDataBinding化する
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        val listViewModel = ListViewModel()
        // ViewModelでデータを取得するロジックを記載
        val taskList = listViewModel.loadData()
        val listAdapter = TaskAdapter(applicationContext, taskList)
        binding.listview.adapter = listAdapter

// 省略

実際に使ってみて

感想を書きます。学習コストは少し高いと思いますが、便利でした。(DataBindingの知識やRxJavaの知識が必要などの学習コストは必要かと思います)

目的がわかりやすい

Activity、ViewModel、Modelのそれぞれが明確な役割を持たせられるので、修正箇所がわかりやすい、コードを見て、他の人と認識合わせがしやすいなどのメリットがあると思います。

それぞれにどこまでの責務を持たせるかは考える必要があると思いますが、便利です。

まだまだ、改善の余地があるので、ブラッシュアップはしていきたいと思います。

参照

Android MVVM 設計 2