프래그먼트의 정의 및 생명주기에 대한 부분은 앞서 포스팅한 게시글을 참조하시면 됩니다.
[Android/안드로이드] Activity/Fragment 생명 주기
1. Activity 생명 주기 액티비티의 생명 주기는 7가지로 구성되어 있다. 아래에서 각각의 생명 주기에 대해 알아보자. 1-1) onCreate() 액티비티의 생명 주기가 진행되는 동안 초기화되어 있어야 하는
leehochang.tistory.com
1. FragmentManager
액티비티내에서 프래그먼트를 관리하는 객체이다.
Fragment Transaction을 통한 프래그먼트 추가, 삭제, 교체 등 작업을 할 수 있다.
또한 백 스택에 추가, 삭제 등의 작업도 가능하다.
1-1) FragmentManager 접근
액티비티에서 접근
getSupportFragmentManager() 를 통해 접근
프래그먼트에서 접근
프래그먼트 내 하나 이상의 프래그먼트를 호스팅할 수 있다. 그래서 2가지 관점에서 봐야한다.
하위 프래그먼트 매니저 접근 : getChildFragmentManager()
호스트 접근 : getParentFragmentManager()
액티비티 - 프래그먼트 - 하위 프래그먼트 내 FragmentManager 관계
예제 1을 위주로 살펴보자. Activity - Fragment - 2 Child Fragment 구조를 가지고 있다.
이러한 구조일 경우 프래그먼트 매니저에 접근해야할 경우 어느 레벨이냐에 따라 상대적이기 때문에 이를 염두에 두고 접근해야한다.
1-2) 백 스택 관리
FragmentTransaction을 addToBackStack()로 백스택에 추가하거나 popBackStack()로 꺼낼 수 있다.
백스택에 추가하게 되면 스택의 형태로 각각 쌓이게 되며 popBackStack()을 통해 꺼내게 되면 역연산이 되는 결과가 나온다.
ex) add의 트랜잭션을 백스택에 담은 후 꺼낼 때는 remove()가 연산되어 나오게 된다.
즉, 트랜잭션을 통해 연산이 되기 전 상태를 저장해둬서 이전 상태로 되돌릴 수 있도로 도와준다
1-3) FragmentTransaction
Fragment를 추가, 삭제, 교체 등과 같은 연산의 집합을 나타내는 class이다.
메소드는 add, remove, replace, hide, show, attach ,detach 등의 메소드가 제공된다.
그리고 백스텍에 추가할지 하지 않을지에 대한 처리도 가능하다
ex)
supportFragmentManager.commit {
replace<ExampleFragment>(R.id.fragment_container)
addToBackStack("name") // name can be null
}
2. Activity - Fragment 간 데이터 공유
이전에는 bundle을 사용하여 데이터를 공유 했지만, 최근에는 ViewModel + LiveData를 사용하여 데이터를 간편하게 공유할 수 있다. 그래서 이후 예제에서는 ViewModel + LiveData를 사용해서 구현해보고자 한다.
class ItemViewModel : ViewModel() {
private val mutableSelectedItem = MutableLiveData<Item>()
val selectedItem: LiveData<Item> get() = mutableSelectedItem
fun selectItem(item: Item) {
mutableSelectedItem.value = item
}
}
class MainActivity : AppCompatActivity() {
private val viewModel: ItemViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.selectedItem.observe(this, Observer { item ->
})
}
}
class ListFragment : Fragment() {
private val viewModel: ItemViewModel by activityViewModels()
fun onItemClicked(item: Item) {
viewModel.selectItem(item)
}
}
위의 예제에서는 ViewModelProvider의 스코프에 대해 유의해야한다. ListFragment에서 activityViewModels()로 액티비티와 뷰모델에 대한 스코프이기 때문에 뷰모델이 동일하다. 그러나 viewModels()로 받을 경우 다른 뷰모델이 생성되는 것이다.
3. Fragment 간 데이터 공유
class ListViewModel : ViewModel() {
val filters = MutableLiveData<Set<Filter>>()
private val originalList: LiveData<List<Item>>() = ...
val filteredList: LiveData<List<Item>> = ...
fun addFilter(filter: Filter) { ... }
fun removeFilter(filter: Filter) { ... }
}
class ListFragment : Fragment() {
private val viewModel: ListViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewModel.filteredList.observe(viewLifecycleOwner, Observer { list ->
}
}
}
class FilterFragment : Fragment() {
private val viewModel: ListViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewModel.filters.observe(viewLifecycleOwner, Observer { set ->
}
}
fun onFilterSelected(filter: Filter) = viewModel.addFilter(filter)
fun onFilterDeselected(filter: Filter) = viewModel.removeFilter(filter)
}
3. 상위 Fragment와 하위 Fragment 간 데이터 공유
class ListFragment: Fragment() {
private val viewModel: ListViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewModel.filteredList.observe(viewLifecycleOwner, Observer { list ->
}
}
}
class ChildFragment: Fragment() {
private val viewModel: ListViewModel by viewModels({requireParentFragment()})
...
}
각 예제들은 안드로이드 공식문서에서 제공하는 예제들이 아주 간단하게 잘 되어 있어 인용하였습니다.
[참고]
https://developer.android.com/guide/fragments/fragmentmanager
'안드로이드 > 개념' 카테고리의 다른 글
[Android/안드로이드] Context란? (0) | 2021.08.08 |
---|---|
[Android/안드로이드] Activity/Fragment 생명 주기 (0) | 2021.07.21 |
안드로이드 단위 ( px, dp, sp, mm, in ) (0) | 2021.07.02 |