성장기록지
Fragment Manager란? 본문
공식문서의 말대로 Jetpack Navigation을 사용한다면 큰 의미가 없겠지만,
프래그먼트를 사용하는 모든 앱은 어느 정도 FragmentManager를 사용하므로
Fragment Manager가 무엇이고 어떻게 작동하는지 파악하는 것이 중요하다 생각하여 학습을 진행한다.
FragmentManager
앱 프래그먼트에서 프래그먼트를 추가, 삭제 또는 교체하고 백 스택에 추가하는 등의 작업을 실행하는 클래스이다.
Activity, Fragment에서 접근가능하다.
FragmentActivity 에서 구현하므로, 해당 및 서브클래스에서는getSupportFragmentManager() 메서드를 통해 FragmentManager에 액세스할 수 있다.
아래와 같은 Fragment Manager가 있다고 하자.
HostActivity 안에 Host Fragment가 있고, 그 안에 Child Fragement가 있다. (Fragment의 modulality에 의해 가능)
그렇다면 Fragment Manager에 접근할 수 있는 영역이 3개가 생긴것이다.
위의 그림을 그래프로 도식화 해보자면 아래와 같다.
프래그먼트는 하나 이상의 하위 프래그먼트를 호스팅할 수 있다. 프래그먼트 내에서 getChildFragmentManager()를 통해 프래그먼트의 하위 요소를 관리하는 FragmentManager 참조를 가져올 수 있다.
호스트 FragmentManager에 액세스해야 한다면 getParentFragmentManager()를 사용하면 된다.
FragmentManager 활용하기
FragmentManager 는 백 스택을 관리한다. 추가, 삭제 등의 작업은 FragmentTransaction 이라는 단일 단위로 함께 커밋된다. addToBackStack() 을 호출하여 트랜잭션을 프래그먼트 백 스택에 추가할 수 있다.
사용자가 뒤로가기 버튼을 누르면 FragmentManager.popBackStack() 을 호출하게 되고 최상위 프래그먼트가 트랜잭션이 스택에서 사라진다.
스택에 더 이상 FragmentTransaction 가 없고 개발자가 하위 프래그먼트를 사용하지 않는 경우 뒤로 이벤트가 액티비티까지 간다!
트랜잭션에 여러 개의 변경을 추가하고 (add() or remove()) addToBackStack() 을 호출하면 하나의 트랜잭션으로 백 스택에 추가되고 뒤로가기 누르면 한꺼번에 되돌려진다.
supportFragmentManager.commit {
replace<ExampleFragment>(R.id.fragment_container)
setReorderingAllowed(true)
addToBackStack("name") // name can be null
}
3. 기존 Fragment 찾기
findFragmentById() 또는 findFragmentByTag() 를 사용하여 레이아웃 컨테이너 내의 현재 프래그먼트 참조를 가져온다.
- findFragmentById() 로 찾기
supportFragmentManager.commit {
replace<ExampleFragment>(R.id.fragment_container)
setReorderingAllowed(true)
addToBackStack(null)
}
...
val fragment: ExampleFragment =
supportFragmentManager.findFragmentById(R.id.fragment_container) as ExampleFragment
- findFragmentByTag() 로 찾기
supportFragmentManager.commit {
replace<ExampleFragment>(R.id.fragment_container, "tag")
setReorderingAllowed(true)
addToBackStack(null)
}
...
val fragment: ExampleFragment =
supportFragmentManager.findFragmentByTag("tag") as ExampleFragment
4. Fragment Defendencies 제공
기본적으로 FragmentManager 는 프레임워크에서 제공하는 FragmentFactory 를 사용하여 프래그먼트의 새 인스턴스를 만든다. 이 기본 팩토리는 리플렉션을 사용하여 프래그먼트 인자가 없는 기본 생성자를 찾아 호출한다. 즉 기본 팩토리를 사용해서 프래그먼트에 Defendencies 를 제공할 수 없다.
종속 항목을 제공하거나 맞춤 생성자를 사용하려면 대신 맞춤FramentFactory 서브 클래스를 만들고FragmentFactory.instantiate 를 재정의 해야한다.
class MyFragmentFactory(val repository: DessertsRepository) : FragmentFactory() {
override fun instantiate(classLoader: ClassLoader, className: String): Fragment =
when (loadFragmentClass(classLoader, className)) {
DessertsFragment::class.java -> DessertsFragment(repository)
else -> super.instantiate(classLoader, className)
}
}
class MealActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
supportFragmentManager.fragmentFactory = MyFragmentFactory(DessertsRepository.getInstance())
super.onCreate(savedInstanceState)
}
}
위 방법 이외에도 companion object 를 사용하여 프래그먼트 내에서 인자를 전달할 수 있다.
'안드로이드' 카테고리의 다른 글
Compose State와 State hoisting (0) | 2025.01.08 |
---|---|
Android의 Clean Architecture란? (0) | 2025.01.07 |
android 권장 아키텍쳐란? (0) | 2025.01.02 |
사용하기 전에 알아보는 Jetpack Room (0) | 2024.12.21 |
안드로이드 Life Cycle (with Activity,Fragment) (1) | 2024.12.20 |