본문 바로가기
Android Application/기초 사용법

안드로이드 뷰모델(ViewModel) 사용하기(with LiveData)

by sdchjjj 2023. 3. 28.
728x90

안녕하세요.

이번 포스팅에서는 프래그먼트에서 뷰모델과 라이브 데이터를 사용해 보겠습니다.

 

언어: 코틀린

sdk vsersion

  - compile: 33

  - min: 21

  - target: 33

 

우선 프래그먼트를 하나 생성하겠습니다.

Fragment (with ViewModel)로 생성해 주면 되겠습니다(figure1 참조).

figure1. create fragment

 

그럼 아래와 같이 프래그먼트가 생성되는데, 이 상태에서 뷰모델을 그대로 사용하겠습니다.

PracticeFragment.kt

class BlankFragment : Fragment() {

    companion object {
        fun newInstance() = BlankFragment()
    }

    private lateinit var viewModel: BlankViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_blank, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(BlankViewModel::class.java)
        // TODO: Use the ViewModel
    }

}

 

 

함께 생성된 뷰모델을 아래와 같이 바꿔줍니다.

PracticeViewModel.kt

class PracticeViewModel : ViewModel() {

    private val _testNumber = MutableLiveData(0)
    val testNumber: LiveData<Int> get() = _testNumber

    fun onButtonClicked() {
        setTestText(testNumber.value!! + 1)
    }

    private fun setTestText(number: Int) {
        _testNumber.value = number
    }
}

버튼을 클릭하면 현재 숫자에 1을 더하여 텍스트에 나타나도록 구현한 코드입니다.

 

다음은 프래그먼트의 layout xml을 수정해 줍니다.

fragment_practice.xml

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

    <TextView
        android:id="@+id/test_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="버튼"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 

프래그먼트에서는 뷰바인딩을 사용하여 뷰를 참조하겠습니다.

뷰바인딩은 아래 포스팅을 참고해 주세요.

https://it-of-fortune.tistory.com/21

 

안드로이드 ViewBinding(뷰바인딩) 구현

안녕하세요. 이번 포스팅에서는 안드로이드 프래그먼트에서의 뷰바인딩 구현을 진행해 보겠습니다. 언어: 코틀린 sdk vsersion - compile: 33 - min: 21 - target: 33 바인딩 진행 전 사전 준비 작업입니다.

it-of-fortune.tistory.com

 

프래그먼트를 아래와 같이 수정하였습니다.

PracticeFragment.kt

class PracticeFragment : Fragment() {

    companion object {
        fun newInstance() = PracticeFragment()
    }

    private var _binding: FragmentPracticeBinding? = null
    private val binding get() = _binding!!

    private lateinit var viewModel: PracticeViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentPracticeBinding.inflate(layoutInflater, container, false)
        return binding.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this)[PracticeViewModel::class.java]
        binding.button.setOnClickListener {
            viewModel.onButtonClicked()
        }
        viewModel.testNumber.observe(viewLifecycleOwner) {
            binding.testText.text = it.toString()
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

 

현재 구현한 동작의 흐름을 간단하게 풀어보자면,

버튼 클릭 -> 뷰모델의 onButtonClicked 호출 -> 뷰모델에서 1을 더한 숫자를 _testNumber MutableliveData에 set -> 이를 바라보고 있던 testNumber LiveData의 값 또한 변경 -> testNumber를 관찰중인 Fragment에서 변화를 감지하고 변경된 값을 TextView에 set

이런 식의 흐름이 되겠습니다.

 

figure2. run

의도한 대로 동작하는 것을 확인할 수 있습니다.

 

이번 내용을 데이터바인딩을 통해 구현하는 방법이 있습니다. 아래 포스팅을 참고해 주세요.

https://it-of-fortune.tistory.com/23

 

안드로이드 데이터바인딩(dataBinding) 사용

안녕하세요. 이번 포스팅에서는 저번 포스팅에서 사용했던 프래그먼트와 뷰모델을 이용해 데이터바인딩을 구현해 보도록 하겠습니다. 아래 링크에서 이전에 구현한 내용을 참고해 주세요. 새

it-of-fortune.tistory.com

 

이번 포스팅은 여기서 마치겠습니다.

 

감사합니다.

728x90

댓글