-
Android Kotlin Fundamentals - ViewModel(2)Android 2021. 5. 30. 09:37
Activity ViewModel을 활용한 Fragment 간 데이터 공유
- Fragment가 N 개인데, Data의 공유가 필요한 경우
- Fragment에서 처리한 데이터에 따라 Activity의 데이터 갱신이 필요한 경우
보통 위와 같은 이유로 sharedViewModels를 사용하는 케이스가 있다.
1. fragment-ktx를 사용하지 않을 경우
SharedViewModel, Fragment들을 아래와 같이 간단하게 구현
class SharedViewModel : ViewModel() { val message = MutableLiveData<String>() fun sendMessage(msg:String){ message.value = msg } }class MessageReceiverFragment:Fragment() { private val model by lazy { ViewModelProvider(requireActivity(), object : ViewModelProvider.Factory { override fun <T : ViewModel?> create(modelClass: Class<T>): T { return SharedViewModel() as T } }).get(SharedViewModel::class.java) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { val binding:FragmentReceiverBinding = DataBindingUtil.inflate( inflater, R.layout.fragment_receiver, container, false) model.message.observe(viewLifecycleOwner, Observer { binding.textViewReceiver.text = it }) return binding.root }class MessageSenderFragment:Fragment() { private val model:SharedViewModel by lazy { ViewModelProvider(requireActivity(), object : ViewModelProvider.Factory { override fun <T : ViewModel?> create(modelClass: Class<T>): T { return SharedViewModel() as T } }).get(SharedViewModel::class.java) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val binding:FragmentSenderBinding = DataBindingUtil.inflate( inflater, R.layout.fragment_sender, container, false ) binding.button.setOnClickListener { model.sendMessage("ViewModel TEST") } return binding.root }SharedViewModel을 인스턴스를 얻을 때 ViewModelProvider의 첫번째 생성자 매개변수인 ViewModelStoreOwner를 Fragment들이 속해있는 부모 Activity로 지정하자. 그러면 각 프레그먼트는 동일한 SharedViewModel 인스턴스를 얻게 된다. SharedViewModel의 생명주기는 Activity를 따르게 되고, Fragment의 생명주기는 Activity의 서브셋이므로 Fragment의 생명주기 동안에 자유롭게 데이터를 공유할 수 있게 된다.
2. fragment-ktx를 사용할 경우
아래와 같이 activityViewModels를 사용하여 정의한다.
private val sharedModel by activityViewModels<SharedViewModel> { object : ViewModelProvider.Factory{ override fun <T : ViewModel?> create(modelClass: Class<T>): T = SharedViewModel() as T } }Activity범위내에서 ViewModel을 공유하여 프레그먼트가 데이터를 공유하는 경우 다음과 같은 장점이 있다.
- Activity는아무것도 할 필요가 없거나 Fragment 커뮤니케이션에 관해 알 필요가 없다
- Fragment는 SharedViewModel외에 다른 부분에 대해서 서로 알 필요가 없다. Fragment 중 하나가 사라져도 다른 프레그먼트는 평소처럼 동작한다.
- 각 Fragment는 자체 생명주기를 가지고 있고, 다른 Fragment의 생명주기에 영향을 주거나 받지 않는다. 한 Fragment가 다른 Fragment를 대체해도 UI는 아무 문제 없이 계속 작동한다.
References
- https://developer.android.com/topic/libraries/architecture/viewmodel
- https://thdev.tech/androiddev/2020/07/13/Android-Fragment-ViewModel-Example/
- https://charlezz.medium.com/viewmodel%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-viewmodel-%EC%B4%88%EB%B3%B4%EB%A5%BC-%EC%9C%84%ED%95%9C-%EA%B0%80%EC%9D%B4%EB%93%9C-e1be5dc1ac18
'Android' 카테고리의 다른 글
LiveData beyond the ViewModel (0) 2021.06.04 LiveData (0) 2021.05.30 Android Kotlin Fundamentals - ViewModel(1) (0) 2021.05.29 ViewModel (0) 2021.05.28 Navigation Component(2) (0) 2021.05.19