Android Jetpack Architecture/ViewModel
ViewModel (Fragment간 데이터 공유 및 통신하기)
hik14
2020. 8. 21. 16:37
ViewModel이 없이 하나의 Activity에서 일반적으로 여러 개의 Fragment와의 데이터를 공유하고 전달하기 위해서는
Activity가 인터페이스를 구현하고 그 인터페이스의 참조(context)를 각 Fragment에 넘겨준 후 호출시키는 방법으로 통신을 하는 것이 기본적이다.
하지만 두 fragment가 모두 인터페이스 설명을 정의해야 하고 소유자 Activity가 두 fragment를 함께 결합해야 하므로 이 사례는 간단히 처리할 수 있는 작업이 아닙니다. 또한 두 fragment는 모두 다른 fragment가 아직 생성되지 않았거나 표시되지 않은 시나리오도 처리해야 합니다.
ViewModel을 사용하면 이러한 Activity 및 Fragment 간 데이터의 공유 및 통신이 쉬어지고 코드가 많이 간결해진다.
예제)
class SharedViewModel : ViewModel() {
val selected = MutableLiveData<Item>()
fun select(item: Item) {
selected.value = item
}
}
class MasterFragment : Fragment() {
private lateinit var itemSelector: Selector
// Use the 'by activityViewModels()' Kotlin property delegate
// from the fragment-ktx artifact
private val model: SharedViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
itemSelector.setOnClickListener { item ->
// Update the UI
}
}
}
class DetailFragment : Fragment() {
// Use the 'by activityViewModels()' Kotlin property delegate
// from the fragment-ktx artifact
private val model: SharedViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
// Update the UI
})
}
}
두 Fragment모두 자신이 포함된 Activity을 검색합니다.
kotlin : private val model: SharedViewModel by activityViewModels()
java : model = new ViewModelProvider(requireActivity()). get(SharedViewModel.class);
그러면 각 Fragment ViewModelProvider를 가져올 때 이 Activity으로 범위가 지정된 동일한 SharedViewModel 인스턴스를 받습니다.
장점
- Activity는 아무것도 하지 않아도 되거나, 이 커뮤니케이션에 관해 어떤 것도 알 필요가 없습니다.
- 프래그먼트는 SharedViewModel 외에 서로 알 필요가 없습니다.
- Fragment 중 하나가 사라져도 다른fragment는 계속 평소대로 작동합니다.
- 각 Fragment는 자체 수명 주기가 있으며, 다른 Fragment 수명 주기의 영향을 받지 않습니다. 한 프래그먼트가 다른 프래그먼트를 대체해도, UI는 아무 문제없이 계속 작동합니다.