sharedViewModel, Android Fragment간의 ViewModel공유하기
https://thdev.tech/androiddev/2020/07/13/Android-Fragment-ViewModel-Example/
sharedViewModel
https://myung6024.tistory.com/188
Android Fragment간의 ViewModel공유하기
안드로이드는 AAC-ViewModel을 제공하는데 기본 3가지를 제공한다.
-Activity에서 만 사용하는 경우
-Fragment에서 만 사용하는 경우
-Activity를 기준으로 Fragment에서 공유해서 사용해야 할 경우
1,2번 케이스는 그냥 자기 자신만 사용하는 경우에 흔하게 사용한다.
3번의 케이스는 Activity는 하나이고, Fragment가 여러개인데 데이터 관리는 Activity만을 기준으로 처리하는 경우가 있다.
이 경우 3번 케이스를 사용하는데, Fragment-KTX를 활용하면 매우 쉽게 접근할 수 있다.
이 글에서는
-Activity/Fragment에서 자신의 ViewModel을 생성해 사용하는 방법 알아보기
-Activity ViewModel을 활용하여 Fragment들에서 사용하는 방법 알아보기
-Fragment의 ChildFragment간에 ViewModel을 공유하는 방법(Activity ViewModel을 활용하지 않고)
Activity/Fragment에서 자신의 ViewModel을 생성해 사용하는 방법 알아보기
가장 일반적으로 사용하는 방법은 AAC-ViewModel사용 방법인데,
Activity/Fragment구분 없이 각자가 자기 자신의 ViewModel을 생성하여, 자기 자신의 Lifecycle을 따르는 방법이다.
MainViewModel이 아래와 같이 저의되어 있고, 이를 Activity에서 초기화 한다.
class MainViewModel: ViewModel(){
private val _updateActivityCount = MutableLiveData<Int>(0)
val updateActivityCount: LiveData<Int> get() = _updateActivityCount
fun insertCountTwo(){
_updateActivityCount.value = (updateActivityCount.value ?: 0) + 2
}
}
Activity에서는 아래와 같이 ViewModel을 초기화할 수 있는데 종류별로 다 기입해본다.
private val viewModel: MainViewModel by lazy{
ViewModelProvider(this@MainActivity, object: ViewModelProvider.Factory{
override fun<T : ViewModel?> create(modelClass: Class<T>): T{
return MainViewModel() as T
}
}).get(MainViewModel::class.java)
}
Fragment도 ViewModel사용하는 방법은 큰 차이가 없다.
Activity ViewModel과 Fragment ViewModel의 관계
각각을 따로 생성했기 때문에 ViewModel은 Activity와 Fragment각각 따로따로 생성되고,
서로 의존성은 존재하지 않는다.
Activity ViewModel을 활용하여 Fragment들에서 사용하는 방법 알아보기
Activity viewModel을 공유해서 사용하는 경우는 어떤 경우가 있을까?
-Fragment가 N개인데, Data의 공유가 필요한 경우
-Fragment에서 처리한 데이터에 따라 Activity의 데이터 갱신이 필요한 경우
보통 위와 같은 이유로 sharedViewModels를 사용하는 케이스가 있다.
액티비티에서 초기화하고, Fragment에서 당겨다 쓰려면 어떻게 해야 할까?
아래의 코드에서는 requireActivity()가 가장 중요하다.
Fragment이기 때문에 FragmentViewModelStoreOwner를 활용하지 않고, Activity의 ViewModelStoreOwner를
활용하여 이미 생성된 Activity의 ViewModel을 활용할 수 있다.
private val activityViewModel: MainViewModel by lazy{
ViewModelProvider(requireActivity(), object: ViewModelProvider.Factory{
override fun<T: ViewModel?> create(modelClass: Class<T>): T = MainViewModel as T
}).get(MainViewModel::class.java)
}
sharedViewModels의 사용은 매우 간단한데 fragment-ktx활용하는 경우에는
activityViewModels를 사용하여 간단하게 사용하는게 가능하다.
private val activityViewModel: MainViewModel by activityViewModels{
object: ViewModelProvider.Factory{
override fun<T: ViewModel?> create(modelClass: Class<T>): T = MainViewModel() as T
}
}
좀 더 알아보자
activityViewModels는 무조건 Activity에서 초기화가 이루어진다는 전제는 없고, 이런 경우도 있다.
- Activity에서는 초기화가 불필요하고, 그냥 fragment에서 만 필요로 한다.
결국 ChildFragment간의 데이터 공유가 필요한 케이스가 생긴다는 것이다.
이 경우는 ViewPager를 활용할 경우 ViewPager간의 데이터 교환이 필요할 수 있다.
이런 경우 activityViewModels를 활용할 수 있으나 activity에서는 ViewModel 초기화가 필요치 않다.
이럴 경우에는 1개 이상의 Fragment에서 activityViewModels만을 진행한다.
핵심은 Activity의 ViewModelStoreOwner를 활용하기 때문에 Fragment만 초기화 코드가 존재하더라도,
Activity가 관리하는 ViewModel이 생성되며, Lifecycle에 따라 onDestroy를 처리한다.
Activity에서는 사용하지 않는 불필요한 코드를 가질 필요가 없다.
class MainActivity: AppCompatActivity(){
//View만 초기화
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
val binding = MainActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
class MainFragmentOne: Fragment(){
private val sharedViewModel: SharedViewModel by activityViewModel()
}
class MainFragmentTwo: Fragment(){
private val sharedViewModel: SharedViewModel by activityViewModel()
}
class SharedViewModel: ViewModel(){
}
'안드로이드' 카테고리의 다른 글
[Android] 안드로이드 앱 아이콘(App icon) 사이즈 (0) | 2022.10.25 |
---|---|
디바이스를 구분하는 고유번호 ANDROID_ID 오레오 (0) | 2022.10.25 |
[Android] Architecture, Framework, Platform에 대해 알아보자 (0) | 2022.10.24 |
[Android] 블루투스(Bluetooth) 개발에 대해 알아보자 (0) | 2022.10.24 |
[Android] 블루투스(Bluetooth) Gatt 개발 순서 (0) | 2022.10.24 |