【正社員】還元率83%【フリーランス】マージン一律5万円で案件をご紹介させていただきます。 詳細はこちら

【Android】<Kotlin>ViewModelとLiveDataの基本と使い方をわかりやすく解説!

【Android】<Kotlin>ViewModelとLiveDataの基本と使い方をわかりやすく解説!
すだ

みなさまこんにちは〜!
メモリアインクのすだです。

今回は、ViewModelとLiveDataを使ったUI実装について、Kotlinのコードを使ってわかりやすく説明していきます。

この記事を読んでわかること…
・ViewModelとは?
・LiveDataとは?
・ViewModelとLiveDataを使った実装方法

目次

環境

  • Kotlin (ver 1.9.0)
  • Android Studio (Giraffe | 2022.3.1 Patch 3)

ViewModelとは?

ViewModel(ビューモデル)とは、
Androidアプリで「画面の状態(UIのデータ)を安全に保持・管理する」ための仕組みです。
Jetpackライブラリの1つで、Kotlinでも非常によく使われます。

ViewModelは、Androidアプリでよく採用されているMVVMアーキテクチャ(Model-View-ViewModel)において、
「画面のロジックと状態を管理する役割」を担います。

なぜViewModelが必要なのか

Activity や Fragment は画面のライフサイクルに従って何度も作り直されるため、変数で保持していたデータが消えてしまうことがあります。

例)画面回転で困るパターン:

class MainActivity : AppCompatActivity() {
    var counter = 0 // ← 画面回転で初期値に戻ってしまう

    ...
}

→ViewModelは ActivityやFragmentとは別のライフサイクルを持つため、
画面が一時的に破棄されても、データは保持され続けます。

ViewModelの基本的な使い方

基本的には、以下のようにViewModel()を継承したViewModelクラスを作成します。

ViewModelクラス

class LikeViewModel : ViewModel() {
    var likeCount = 0

    fun addLike() {
        likeCount++
    }
}

クラス内でプロパティや関数を定義してください。

そして、以下のようにActivityやFragmentから呼び出します。

Activityからの呼び出し

class MainActivity : AppCompatActivity() {

    private lateinit var viewModel: LikeViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel = ViewModelProvider(this)[LikeViewModel::class.java]

        val button = Button(this).apply {
            text = "いいね: ${viewModel.likeCount}"
            setOnClickListener {
                viewModel.addLike()
                text = "いいね: ${viewModel.likeCount}"
            }
        }

        setContentView(FrameLayout(this).apply {
            addView(button)
            setPadding(64, 200, 64, 64)
        })
    }
}

ViewModelProvider(this)を使って、このActivityが表示されている間だけ有効なViewModelのインスタンスを取得します。
つまり、ViewModelの生存期間(ライフサイクル)をActivityに紐づけて管理しているということです。

LiveDataとは?

LiveData(ライブデータ)も、Googleの Jetpack ライブラリの一部で、
データの変化をリアルタイムにUIに反映することができる「監視可能なデータホルダー」です。

データが変わったら自動で教えてくれる仕組みを持っており、
LiveDataはViewModelと組み合わせて使うのが基本です。

図解すると以下のようになります。

[Model] ← API/DB など
   ↓
[ViewModel] → データ保持・処理(MutableLiveDataに値をセット)
   ↓
[LiveData] → 値が変わったらUIへ通知
   ↓
[View](Activity/Fragment) → observe()してUIを更新

ViewModelと組み合わせたLiveDataの使い方

まずはViewModelクラスを定義します。

ViewModelクラス

class LikeViewModel : ViewModel() {

    // MutableLiveDataで状態を保持
    private val _likeCount = MutableLiveData(0)
    val likeCount: LiveData<Int> get() = _likeCount

    fun addLike() {
        _likeCount.value = (_likeCount.value ?: 0) + 1
    }
}

MutableLiveDataLiveData を継承したクラスで、値を変更できる機能が追加されています
value プロパティを使って値を変更できます。(ここでは0を初期値として置く)

そして5行目のLiveData<Int>は読み取り専用のLiveData(変更不可)です。
likeCount の value が変わると、likeCount を監視しているUIに通知が届きます。

likeCount 自体が更新されるわけではなく、
_likeCount の中身(実体)をlikeCountが参照している というイメージです。

_likeCount = 内部の状態(変更可能)
likeCount = 外部に公開する読み取り専用の状態

class MainActivity : AppCompatActivity() {

    private lateinit var viewModel: LikeViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel = ViewModelProvider(this)[LikeViewModel::class.java]

        val likeButton = Button(this)

        // LiveDataの監視 → 値が変わるたびにUIを更新
        viewModel.likeCount.observe(this) { count ->
            likeButton.text = "いいね: $count"
        }

        // ボタン押下 → addLike() を呼び出し(状態を更新)
        likeButton.setOnClickListener {
            viewModel.addLike()
        }

        val layout = FrameLayout(this).apply {
            addView(likeButton)
            setPadding(64, 200, 64, 64)
        }

        setContentView(layout)
    }
}

ViewModelの likeCountobserve() すると、その LiveData の値が変更されたときに、自動的に通知を受け取ることができます。

まとめ

いかがでしたでしょうか〜!

・ViewModel「UIの状態を保持するクラス」
・LiveData「状態の変化を通知する仕組み」

この2つを組み合わせることでMVVMアーキテクチャが実現でき、
UIの状態管理が楽になり、画面回転などにも強いアプリを作成することができます。

ぜひ実践してみてください!

すだ

技術者としてのキャリアパスを次のレベルへと進めたい皆様、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
を通じて、
自分の市場価値をさらに向上させてみませんか?

それではまた次の記事でお会いしましょう!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

弊社テックブログをご愛読いただきありがとうございます。
当テックブログを運用している株式会社メモリアインクは、
【正社員】還元率83%
【フリーランス】マージン一律5万円で案件のご紹介
と、エンジニアの皆様に分かりやすい形で稼げる仕組みを構築し提供させていただいております。

コメント

コメントする

目次