[Android] FragmentManager

sw·2021년 12월 20일
0

1. FragmentManager란

Fragment에서 작업을 추가, 삭제 또는 교체하고 백 스택에 추가하는 등의 작업을 실행하는 클래스


2. FragmentManager에 액세스하는 방법

  1. Activity에서 액세스
    getSupportFragmentManager()메서드를 통해 FragmentManager를 사용할 수 있다. (Kotlin에서는 supportFragmentManager() 사용)

  2. Fragment에서 액세스
    Activity뿐만 아니라 Fragment도 하위 Fragment를 1개 이상 호스팅할 수 있다. 하위요소를 관리하는 FragmentManager에는 getChildFragmentManager()로, 호스트 FragmentManager에 액세스할 땐 getParentFragmentManager()를 사용한다.



3. Fragment와 FragmentManager의 관계

  • 연두색은 Fragment의 Host Activity이다.
  • Example 1에서는 하늘색으로 표시된 Fragment가 하위의 Fragment 2개를 호스팅하고 있다.
  • Example 2에서는 하늘색으로 표시된 Fragment가 ViewPager2를 구현한 하위 Fragment 1개를 호스팅하고 있다.
  • Fragment와 FragmentManager의 관계는 아래와 같다




4. FragmentManager 사용

  • FragmentManager는 Fragment 백스택을 관리한다. 백스택이란 현재 실행하는 FragmentTransaction의 상태를 기억하기 위해 만들어진 개념이다. Fragment를 추가/삭제하는 작업은 FragmentTransaction이란 단위로 commit된다.

  • 뒤로가기 버튼이나 FragmentManager.popBackStack()을 호출하는 경우 최상위 FragmentTransaction이 스택에서 사라진다.

  • FragmentTransaction에서 addToBackStack()을 호출하면 ex) 여러 개의 Fragment 추가,교체 등 많은 작업들이 1개의 FragmentTransaction에 포함되고 popBackStack()로 한 번에 취소할 수 있다.

  • 기존 Fragment 찾기

  1. findFragmentById()를 이용해서 Fragment Container의 현재 참조하고 있는 Fragment를 가져올 수 있다.
   supportFragmentManager.commit {
   	replace<ExampleFragment>(R.id.fragment_container)
   	setReorderingAllowed(true)
   	addToBackStack(null)
	}
	
    ... 
val fragment: ExampleFragment =
supportFragmentManager.findFragmentById(R.id.fragment_container) as ExampleFragment
  1. Fragment에 고유한 Tag를 부여하고 findFragmentByTag()를 사용.layout 내에서 정의되거나 FragmentTransaction내에서 add(), replace()할 때 android:tag XML 속성을 사용해서 태그를 할당한다.
supportFragmentManager.commit {
   replace<ExampleFragment>(R.id.fragment_container, "tag")
   setReorderingAllowed(true)
   addToBackStack(null)
}

...

val fragment: ExampleFragment =
        supportFragmentManager.findFragmentByTag("tag") as ExampleFragment


5. FragmentTransaction 실행

  • layout 내에 Fragment를 표시하려면 FragmentManager를 사용해 FragmentTransaction을 만들고 add()나 replace()를 한다.
supportFragmentManager.commit {
   replace<ExampleFragment>(R.id.fragment_container)
   setReorderingAllowed(true)
   addToBackStack("name") // name can be null
}
  • setReorderingAllowed(true)는 Fragment 전환을 최적화시킨다. commit 시 해당 속성을 지정해주는게 좋다.

  • addToBackStack()호출하면 FragmentTransaction이 백스택에 commit된다. addToBackStack()호출할 때 매개변수로 name을 지정하게 되면 popBackStack()시 해당 name을 이용해 특정 Transaction으로 돌아갈 수 있다.

  • Fragment를 삭제할 때 addToBackStack()을 호출하지 않으면 삭제된 Fragment는 commit시 없어지므로 다시 탐색할 수 없다. 만약에 삭제할 때addToBackStack()을 호출했다면 Fragment는 STOPPED상태에 머물렀다가 나중에 사용자가 뒤로 탐색했을 때 RESUMED상태가 된다.

  • FragmentTransaction내에서 기본 탐색 Fragment를 지정하려면 Transaction에서 setPrimaryNavigationFragment() 메서드를 호출해서 childFragmentManager에 기본 컨트롤이 있어야하는 Fragment 인스턴스를 전달한다.

profile
끄적끄적

0개의 댓글