Android Architecture ComponentsのViewModelを使ってみる

Android Architecture ComponentsのViewModelを使ってみる

  • このエントリーをはてなブックマークに追加

目次

Android Architecture Componentsの背景

Android開発において、近年は、大きな変化が訪れています。

その中でも特に注目したいものが、Android Architecture Components(AAC)です。

AACは、Androidで今まで面倒だったライフサイクルの管理やデータの保持などを扱いやすくするためのライブラリです。

そのAACの中のViewModelについて、今回は紹介したいと思います。

ViewModelの適用手順

それでは、AACのViewModelを実際に使ってみながら、説明していきます。

ViewModelをプロジェクトに導入する

まずは、ViewModelのライブラリを追加していきます

build.gradle (project) にgoogleのリポジトリがなければ、下記のように追加しておきます。

buildscript {
    ・・・
}

allprojects {
    repositories {
        google()
        ・・・
    }
}

次にbuild.gradle (app) に 下記のようにライブラリを追加します。

android {
    ・・・
}
dependencies {
    ・・・
    implementation "android.arch.lifecycle:extensions:1.1.1"
    ・・・
}

これでViewModelが使用できるようになります。

ViewModelを生成する

ライブラリのViewModelを継承したクラスを作成します。
Activityに反映するデータなどは、すべてViewModelで保持するようにします。

import android.arch.lifecycle.ViewModel

class MainViewModel : ViewModel() {
    var name : String  = ""
}

下記のようにViewModelはViewModelProvidersを経由してインスタンスを取得します。

class MainActivity : AppCompatActivity() {

    private lateinit var viewmodel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewmodel = ViewModelProviders.of(this).get(MainViewModel::class.java)
    }
}

このViewModelProvidersで、ViewModelが管理されています。
ViewModelProviders.of()の引数に渡されたActivityやFragmentに紐付いたViewModelのインスタンスを返してくれます。
この例だとMainActivityを渡していますが、ここに仮に別のFragmentを渡した場合には、別のインスタンスが返されます。

ViewModelの値を画面に反映する

ViewModelのインスタンスを取得した後は、ViewModelに対して、値をセットしたり、取得を行います。
ViewModelの値でViewに反映するように記述していきます。

class MainActivity : AppCompatActivity() {

    private lateinit var viewmodel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewmodel = ViewModelProviders.of(this).get(MainViewModel::class.java)

        buttonSet.setOnClickListener {
            viewmodel.name = editName.text.toString()
        }

        buttonGet.setOnClickListener {
            textName.text = viewmodel.name
        }
    }
}

完成

Activityに直接フィールドを持っていた場合には、画面回転などでActivityが破棄されるとフィールドの値も破棄されてしまいます。

そのためsavedInstanceStateを利用して、値の保存と復元が必要でした。
それに対して、ViewModelは破棄されても再度ViewModelProvidersからインスタンスを取得し直せば、元の値が取得できます。

まとめ

今までは画面回転などでActivityが破棄される場合を考慮して実装していたのが、ViewModelを使うことで、その部分を考慮せずに記述できるようになりました。

ViewModelだけでは、そこまで恩恵がないように見えますが、今回は説明しなかったDatabindingやLiveDataも合わせて使うことで、さらにライフサイクルを意識せずに記述していくことが可能になります。

そのため、DatabindingやLiveDataを使用する上でViewModelの適用は基礎となっていきます。また、ViewとViewModelの責務が明確に分かれていき、FatなActivityやFragmentになりづらくなります。

今回は手作業でプロジェクトにViewModelを導入しました。
しかし、Preview版ですがAndroid Studio 3.2からは、新規にFragmentなどを追加する際に、ViewModel付きを導入した状態で作成できるテンプレートが組み込まれています。

今後、Androidアプリ開発においてMVVMでの設計が多くなっていくのは間違いないのかもしれません。

  • このエントリーをはてなブックマークに追加

記事作成者の紹介

カワニシ(フロントエンドエンジニア)

悶絶ブラックなシステムエンジニアからジョブチェンジして、島根でゆるふわにお仕事をしています。 島根でエンストしてるオープンカーがいたら私です。

フロントエンドエンジニア募集中!

×

SNSでも情報配信中!ぜひご登録ください。

×

SNSでも
情報配信中!
SONICMOOV Facebookページ SONICMOOV Twitter
フロントエンドエンジニア募集中!

新着の記事

mautic is open source marketing automation