본문 바로가기
Android/개념 및 정보

[Android] MVVM 의 ViewModel (using LiveData)

by Taehyung Kim, dev 2020. 12. 31.
728x90

안드로이드 아키텍처 중 가장 많이 쓰이는 MVVM 구조에서 VM의 역할을 해주는 ViewModel에 대해서 스터디하였습니다.

 

결과물

버튼을 클릭하면 카운트가 올라가고 가로로 전환 시에도 데이터가 변화하지 않는 것을 확인할 수 있는 간단한 앱입니다.

 

안드로이드는 회전 이벤트가 주어지면 데이터가 사라집니다.

이전에는 bundle을 이용해 onPause() 이벤트에 데이터를 저장하고 다시 onResume()이 되면 bundle로 데이터를 불러왔습니다.

 

그러나 ViewModel을 이용하면 bundle을 이용하지 않아도 데이터를 유지할 수 있습니다.

 

 

프로젝트 생성

먼저 새로운 프로젝트부터 생성해보겠습니다.

저는 Exam_ViewModel 이름으로 생성하였습니다.

 

Gradle

build.gradle(Moduel: Exam_ViewModel.app)에서 ViewModel을 사용하기 위한 Gradle implementaion을 작성해줍니다.

작성한 뒤 sync Now.

dependencies {
	..
    ..
    ..
    
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
}

 

Layout

버튼을 레이아웃을 추가하고 TextView에 id를 부여합니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40sp"
        android:text="0"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/bt_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="up"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_count" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

ViewModel 클래스 작성

ViewModel을 사용하기위한 클래스를 만들어줍니다.

데이터 감지를 위해 LiveData를 사용하였습니다.

package com.example.exam_viewmodel

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class MainViewModel : ViewModel() {

    private val _countData = MutableLiveData<Int>()
    val countData: MutableLiveData<Int>
        get() = _countData

    private var defaultValue = 0

    fun setCount() {
        defaultValue++
        _countData.value = defaultValue
    }
}
  • setCount 함수를 이용해 데이터를 증가시켜줍니다.
  • LiveData의 value에 값의 변화를 줍니다.

 

ViewModelFactory

ViewModel 클래스의 생성을 도와주는 Factory 클래스를 생성합니다.

package com.example.exam_viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import java.lang.IllegalArgumentException

class MainViewModelFactory : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
            return MainViewModel() as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

 

MainActivity

package com.example.exam_viewmodel

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider

class MainActivity : AppCompatActivity() {

    private lateinit var viewModel: MainViewModel

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

        val textView = findViewById<TextView>(R.id.tv_count)
        val button = findViewById<Button>(R.id.bt_count)

        viewModel = ViewModelProvider(this, MainViewModelFactory()).get(MainViewModel::class.java)

        viewModel.countData.observe(this, Observer {
            textView.text = it.toString()
        })

        button.setOnClickListener {
            viewModel.setCount()
        }
    }
}
  • viewModel 인스턴스를 생성합니다.
  • countData를 observe합니다.
  • 데이터가 변화하면 textView에 text를 바꿔줍니다.
  • button을 클릭하면 setCount 함수를 실행합니다.

 

지금까지 ViewModel에 대해서 간단하게 살펴보았습니다.

 

다만 걱정이 되는 부분은 이렇게 사용하는 것이 과연 옳은 것인가하는 물음이 생깁니다.

 

LiveData에 대해서 자세히 공부할 필요성을 느꼈으며 ViewModel 공유에 대해서 스터디가 필요함을 느꼈습니다.

 

또한 ViewModel의 사용이 익숙해진다면 Model 클래스를 이용하여 MVVM 아키텍처 구조로 생성하게 되는 발판이 되리라 생각합니다.

 

다음에는 Model 클래스를 이용하여 MVVM 구조를 가진 간단한 프로젝트를 스터디해보겠습니다.

728x90

댓글