목표
- ViewModel을 이용하여 Fragment간에 데이터를 공유하는 방법을 안다.
ViewModel의 생성 방식
ViewModel은 View(Activity 혹은 Fragment)의 Lifecycle에 Dependent한 Lifecycle을 갖는다. ViewModel 속 데이터가 살아있는 기간이 View가 살아있는 기간보다 길기 때문에 View가 살아 있는 동안은 ViewModel 속 데이터는 유지된다. 그런데 Fragment에는 조금 특이한 성질이 있다. 바로 Fragment의 생명주기는 Fragment가 붙어 있는 Activity에 Dependent한 성질이다.
이러한 성질로 인해 <그림1>과 같이 하나의 Activity에는 여러 개의 Fragment가 존재할 수 있으며, 각 Fragment는 각자의 생명주기에 맞는 ViewModel을 가질 수 있다.
하지만 <그림2>와 같이 Fragment1ViewModel을 Fragment2의 Lifecycle에 Dependent하게 초기화할 경우, ViewModel은 View의 ViewModelStore에 만들어지므로 Fragment1ViewModel 인스턴스가 Fragment2(ViewModel Store)에 새로 생성된다. 이로 인해 Fragment1ViewModel 인스턴스 2개는 서로 간에 데이터를 공유할 수가 없게 된다.
*ViewModelStore의 설명은 아래 글을 참조하자
by activityViewModels를 활용한 Fragment간 데이터 공유
그렇다면 Fragment가 Dependent한 Activity의 ViewModel을 만드는 것은 어떨까? 앞서 3번 글에서 by activityViewModels()는 Fragment에서만 호출하며, Fragment가 붙은 Activity에 종속된다고 하였다.
inline fun <reified VM : ViewModel> Fragment.activityViewModels
우리는 이를 응용하여 다음과 같이 Fragment간에 데이터를 공유하는 ShareViewModel을 만들 수 있다.
private val viewModel: ShareViewModel by activityViewModels()
이 ShareViewModel은 MainActivity 상에서는 by viewmodels()를 활용하여 초기화가 가능하며, Fragment속에서는 by activityViewModels()를 이용하여 초기화가 가능하다. 이 두 방식으로 생성되는 ShareViewModel은 같은 인스턴스를 가리킨다. 즉, 공유된다.
이렇게 할 경우 MainActivity의 ViewModelStore에서 이 ShareViewModel을 하나만 생성하여 서로간에 공유하도록 만든다. 즉 by activityViewModels()가 MainActivity 속 여러 Fragment에서 호출되더라도 하나의 ShareViewModel만 만들어진다. 이를 통해 Fragment 간에 데이터 전달이 가능해진다.
하나의 Activty에 attach된 여러 Fragment들은 Activitiy에 종속되는 ViewModel을 생성함으로써 데이터를 공유 및 전달 할 수 있다.
정리
ViewModel에서 데이터가 유지되는 특징을 이용해 Fragment간 데이터 전달 및 Activity-Fragment 간 데이터 전달이 가능하다는 것을 이해하자.