참고 자료
Android Developer 도큐먼트 - 프래그먼트 개요
Android Developer 도큐먼트 - 프래그먼트 만들기
안드로이드 프로젝트를 할때마다 재사용될 것 같은 뷰는 fragment로 사용하곤 했습니다. 그런데 내가 fragment를 제대로 알고 사용하는걸까? 하는 의심이 들어서 이번 기회에 fragment의 모든~~것을! 알아보도록 하겠습니다. 안드로이드 공식문서를 보면서 차근히 공부해봐욧!
뭐든 기존 기술에 문제가 있거나 개선사항이 필요할 때 새로운 기술이 나오는법이죠! Fragment는 Activity 가 가지고 있는 문제를 해결하기 위해 등장했습니다
Activity가 가지고 있는 문제는 아래 2가지 입니다
1) Activity 안에 코드가 길어지게 되면 코드가 길어지니까 유지보수할 때 관리가 어려워짐
2) 안드로이드 디바이스는 휴대폰,태블릿 등 다양하기 때문에 태블릿UI를 고려할 때 단순 Activity로 화면을 그리기에 한계가 있음
2번 문제를 더 자세히 살펴봅시다 위 그림은 프래그먼트가 정의한 두 가지 UI 모듈이 태블릿 디자인에서는 하나의 액티비티로 조합될 수 있는 반면, 핸드셋 디자인에서는 분리될 수 있다는 것을 나타낸 예시입니다.
프래그먼트는 앱의 전체 UI(User Interface의 약자로, 사용자가 눈으로 볼 수 있는 화면 및 사용자와 앱이 상호작용(버튼 클릭 등)할 수 있는 부분)에서 어딘가에 반복적으로 재사용 가능한 부분을 말합니다.(Fragment의 존재 이유)
프래그먼트는 자체 레이아웃(xml파일을 정의할 수 있음)을 가질 수 있으며 자체 생명 주기를 보유합니다. 또한 자체 입력 이벤트를 받으며 처리할 수 있습니다.(자체 레이아웃을 갖는 것은 선택 사항, 자체 UI가 없는 프래그먼트도 만들 수 있음)
프래그먼트는 독립적으로 존재할 수 없고, 반드시 Activity나 다른 프래그먼트에 호스팅(주인 역할을 하다 / 호스팅되다 = 노예가 되다)되어야 합니다.
따라서 프래그먼트의 뷰 계층 구조는 호스트 뷰 계층 구조의 일부가 됩니다.
Android Jetpack 라이브러리 중 Navigation, BottomNavigationView, ViewPager2 등은 프래그먼트와 호환되도록 설계되어 있어서 프래그먼트가 해당 라이브러리와 함께 자주 사용됩니다.
Android Jetpack 라이브러리 중 Fragment 라이브러리가 등장하면서 Fragment가 하나의 프레임워크 또는 라이브러리화 되었습니다.
Fragment 라이브러리가 제공하는 클래스 중 Fragment 라는 클래스 가 있습니다.
Android Developer 사이트 - Fragment 클래스 공식 문서 와 Fragment 클래스 실제 코드 가 존재합니다.
Android Developer 사이트 - Fragment 클래스 공식 문서에서 Fragment가 Object 클래스를 상속하고 LifecycleOwner, ActivityResultCaller 등 여러 인터페이스를 구현하고 있는 클래스임을 확인할 수 있습니다.
앞으로 언급할 모든 '프래그먼트 클래스' 라는 용어는 말 그대로 '프래그먼트 클래스'를 의미하는 것이고 '프래그먼트 자체 UI' 라는 용어로 프래그먼트의 UI를 의미할 것입니다.
앞서 프래그먼트의 특징에서 언급했듯이, 프래그먼트의 존재 이유는 UI 중에서 재사용 가능한 부분을 재사용하기 위함입니다.
프래그먼트는 자체 UI를 개별적인 청크로써 사용할 수 있습니다. 개별 청크 단위로 다른 곳에서 재사용할 수 있습니다.
Activity : 앱 전체적인 사용자 인터페이스(UI)에 포함될 요소들을 배치하는 곳입니다.
Fragment : 단일 화면이나 화면 일부에 관한 사용자 인터페이스(UI)를 정의하는데 적합합니다.
(위 그림 참고) 하늘색 박스 부분은 Activity에 배치된 NavigationView 이고, 연두색 박스 부분은 프래그먼트 자체 UI입니다. Activity은 연두색 프래그먼트를 호스팅하고 있습니다.
앱의 단일 화면이나 부분 화면을 프래그먼트로 구현하면 런타임 시 UI 모습을 사용자와 상호작용하면서 실시간으로 수정할 수 있습니다.
사용자가 앱을 실행하여 사용하는 도중(Activity is running)에 Activity의 모양을 수정할 수 있다는 의미입니다. 예를 들어 BottomNavigationView가 존재하는 앱에서는 사용자가 '홈 탭'을 클릭하면 홈 화면이 나오고, '마이페이지 탭'을 클릭하면 마이페이지 화면이 나옵니다. 이러한 현상이 런타임동안 사용자와 상호작용을 하면서 앱의 UI가 실시간으로 바뀌는 것이라고 할 수 있습니다.(프래그먼트 추가/교체/삭제 등의 작업이 실행됨으로써 화면이 바뀌는 것처럼 보입니다.)
대신 프래그먼트를 사용하여 런타임 동안 UI를 실시간으로 바꿀 때는 호스트 Activity의 수명 주기가 STARTED 상태 이상에 있는 동안에만 가능합니다.
런타임 동안 프래그먼트의 변경 사항(추가/교체/삭제)이 발생하면 FragmentManager라는 것이 관리하는 프래그먼트 백 스택(Activity 백 스택과 다름) 에 변경 사항 히스토리를 저장하여 기록할 수 있습니다.
프래그먼트 백 스택에 저장된 변경 사항들에 한에서 사용자가 '뒤로' 버튼을 눌렀을 경우 '변경 사항 취소' 가 되어 '되돌리기' 작업을 진행할 수 있습니다.
프래그먼트는 재사용 가능한 자체 UI를 가지기 때문에 어느 Activity에나 호스팅 될 수 있고 어느 프래그먼트에나 호스팅 될 수 있습니다.
따라서 프래그먼트 클래스에는 자체 UI를 관리하는 로직만 구현해야 하고 다른 Activity나 다른 프래그먼트를 직접 조작하는 로직을 포함해서는 안됩니다.(모듈성, 재사용성을 해치게 됨)
즉, 프래그먼트가 다른 Activity나 프래그먼트에 의존하면 안됩니다.
1. 환경 설정
프래그먼트 클래스를 만들어보기 전, 안드로이드 프로젝트에 Jetpack Fragment 라이브러리 종속성을 추가해야 합니다.
Android 라이브러리는 Google Maven Repository에서 찾을 수 있으므로 build.gradle파일(프로젝트 수준)에 Google Maven 저장소를 먼저 추가해야 합니다.
~~~gradle
// build.gradle(Project 수준) 파일
buildscript {
...
repositories {
google()
...
}
}
allprojects {
repositories {
google()
...
}
}
~~~
프로젝트에 Google Maven 저장소를 추가했다면 build.gradle파일(app 수준)에 Jetpack Fragment 라이브러리 종속성을 추가하면 됩니다.
~~~gradle
// build.gradle(App 수준) 파일
dependencies {
// 최신 버전 대입
def fragment_version = "1.2.5"
// Java language implementation(개발 언어 별 선택)
implementation "androidx.fragment:fragment:$fragment_version"
// Kotlin(개발 언어 별 선택)
implementation "androidx.fragment:fragment-ktx:$fragment_version"
}
~~~
2. 프래그먼트 클래스 생성하기
프래그먼트 클래스를 생성한다는 것은 해당 프래그먼트의 자체 UI 조작을 담당하는 클래스를 생성한다는 것입니다.
프래그먼트 클래스는 위 과정에서 추가한 Jetpack Fragment 라이브러리에서 제공하는 Fragment 클래스를 상속하는 클래스를 구현함으로써 생성할 수 있습니다.
Fragment 클래스의 생성자 함수는 두 가지 종류가 있는데 하나는 default 생성자 함수이고, 다른 하나는 default 생성자 함수의 대안책으로 사용할 수 있는 생성자 함수입니다.
대안책으로 사용할 수 있는 생성자 함수를 사용하여 프래그먼트 클래스의 인스턴스를 생성할 경우 장점이 존재합니다. default 생성자 함수를 사용하여 프래그먼트 클래스의 인스턴스를 생성하는 경우에는 클래스 내부에 onCreateView(LayoutInflater, ViewGroup, Bundle) 메소드를 구현해야 합니다. 하지만 대안책으로 사용할 수 있는 생성자 함수를 사용하면 onCreateView() 구현을 생략할 수 있습니다.
* 아래 코드처럼 프래그먼트 클래스를 쉽게 생성할 수 있습니다.
~~~kotlin
// ExampleFragment.kt 파일
import androidx.fragment.app.Fragment
// Default 생성자 함수 사용
class ExampleFragment : Fragment() {
// TODO(onCreateView 메소드 구현하기)
}
~~~
~~~kotlin
import androidx.fragment.app.Fragment
// Alternate 생성자 함수 사용
// 생성자 함수 인자로 프래그먼트 자체 UI 레이아웃이 정의된 xml 파일의 id값을 전달해야 합니다.
class ExampleFragment : Fragment(R.layout.example_fragment) {
}
~~~
* 이렇게 생성한 클래스 내에서 상속한 Fragment 클래스에 포함된 여러 메소드를 override 하여 해당 프래그먼트가 담당할 로직들을 구현하면 됩니다.
3. Activity에 프래그먼트 호스팅 시키기
프래그먼트는 독립적으로 존재할 수 없고, 반드시 Activity나 다른 프래그먼트에 호스팅되어야 합니다.
프래그먼트를 Activity에 호스팅 시키려면 해당 Activity가 FragmentActivity 를 상속하는 Activity여야 합니다.
FragmentActivity
를 상속하는 Activity여야만 해당 Activity 레이아웃 일부분에 프래그먼트 자체 UI를 배치할 수 있습니다.
만약 Activity가 이미 AppCompatActivity 클래스를 상속하고 있다면 FragmentActivity
를 따로 상속할 필요가 없습니다.
AppCompatActivity
가 이미 FragmentActivity
를 상속하는 클래스이기 때문입니다.
Activity에 프래그먼트를 호스팅 시키는 방법은 2가지 방법이 있습니다.
Activity UI 레이아웃 안에 프래그먼트 존재를 정의하여 Activity UI가 Activity 클래스에 inflate될 때 프래그먼트 자체 UI도 자동으로 프래그먼트 클래스에 inflate 시키는 방법
Activity UI 레이아웃 안에 프래그먼트 컨테이너(=이 위치에 프래그먼트 자체 UI가 배치될 것입니다~ 라고 위치를 지정해두는 것)를 정의하고 프로그래밍적으로 해당 컨테이너 안에 프래그먼트를 추가(Add)하는 방법
주의할 점은 두 방법 모두 Activity UI 레이아웃 안에 FragmentContainerView 를 정의함으로써 해당 프래그먼트가 배치될 위치를 정의해야 한다는 점입니다.
FragmentContainerView
는 FrameLayout
에서 제공하지 않는 조작 관련 사항이 추가된 새로운 뷰입니다. 따라서 Activity UI 레이아웃 내에 프래그먼트 자체 UI 위치를 지정할 때는 FragmentContainerView를 사용하길 권장합니다.
(FragmentContainerView가 등장하기 전까지는 Acitivity에 프래그먼트를 호스팅할 때 FrameLayout을 많이 사용했습니다. 또한 애초에 FragmentContainerView가 FrameLayout 클래스를 상속하는 클래스입니다)
첫 번째 방법으로 Activity에 프래그먼트 호스팅시키기
<!-- activity_main.xml 파일 -->
<androidx.constraintlayout.widget.ConstraintLayout
...>
<!-- FragmentContainerView 배치 -->
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:name="com.chohee.fragment.ExampleFragment"/>
</androidx.constraintlayout.widget.ConstraintLayout>
편의상 FragmentContainerView를 한글 번역한 '프래그먼트 컨테이너'라고 부르겠습니다
android:name 속성을 통해 프래그먼트 컨테이너에 추가될 프래그먼트 클래스를 지정합니다. 이 속성을 지정하면 자동으로 일련의 내부 동작이 실행됩니다.
android:name 속성의 내부 동작은 다음과 같습니다. Activity UI 레이아웃이 inflate되는 과정에서 FragmentContainerView가 inflate될 때 자동으로 android:name 속성에 지정된 프래그먼트를 새로운 인스턴스로 생성합니다.
인스턴스(instance)란? -> 클래스(설계도)를 바탕으로 소프트웨어 세계에 구현된 실체(=메모리에 할당)
예 - ExampleFragment라는 클래스를 프로젝트 어딘가에 작성해놓고, MainActivity 클래스에서 val exampleFragment = ExampleFragment() 라는 코드(ExampleFragment 클래스의 생성자 함수를 사용해 인스턴스를 생성하는 코드)를 작성하면 ExampleFragment 클래스(설계도)를 바탕으로 구현된 객체가 메모리에 할당됩니다. 이것을 ExampleFragment 클래스가 인스턴스되었다 라고 합니다.
지정된 프래그먼트의 인스턴스가 생성되면 프래그먼트 수명 주기 메소드 중 onInflate() 메소드가 호출됩니다.
onInflate() 메소드가 호출된 후, 해당 프래그먼트 자체 UI를 프래그먼트 컨테이너 위치에 추가하는 FragmentTransaction이 실행됩니다.(FragmentTransaction은 Android Jetpack Fragment 라이브러리가 제공하는 클래스입니다. 이에 관해서는 이어지는 다음 포스팅에서 다룰 예정입니다)
실제로 테스트해본 결과, activity_main.xml 파일을 위 코드와 같이 구성한 후 앱을 실행하니 MainActivity에 ExampleFragment가 잘 호스팅 되었습니다.(example_fragment.xml의 배경색을 지정해 프래그먼트 영역을 구분함)
두 번째 방법
<!-- activity_main.xml 파일 -->
<androidx.constraintlayout.widget.ConstraintLayout
...>
<!-- FragmentContainerView 배치 -->
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
android:name 속성을 지정하지 않음으로써 Activity UI 레이아웃 안에서 프래그먼트 컨테이너의 위치만 배치합니다.(자동으로 프래그먼트가 인스턴스화 되지 않음)
이러한 두 번째 방법을 사용하면 Activity가 running 상태일 동안(=런타임 동안 =사용자가 앱을 사용할 동안) 프래그먼트 컨테이너 안에 프로그래밍적으로 프래그먼트를 추가/교체/삭제할 수 있습니다.
프로그래밍적으로 프래그먼트를 추가/교체/삭제하려면 프래그먼트를 호스팅하는 Activity 내에서 FragmentManager 클래스를 인스턴스화해야 합니다.(FragmentManager 클래스는 Android Jetpack Fragment 라이브러리에서 제공하는 클래스이고 이에 관해서는 조금 아래에 나올 내용에서 다룰 예정입니다.)
FragmentManager
클래스를 인스턴스화하는 이유는 프래그먼트 추가/교체/삭제 작업을 제공하는 FragmentTransaction
클래스를 사용하기 위함입니다.
(위 그림 참고) FragmentTransaction
클래스는 public 클래스가 아닌 abstract 클래스(추상 클래스)입니다. 이 추상 클래스는 FragmentManager
클래스에 구현되어 있기 때문에 FragmentTransaction
클래스를 사용하기 위해 FragmentManager
클래스를 인스턴스화 하는 것입니다.
프래그먼트를 호스팅하는 Activity 내에서 FragmentManager
클래스를 인스턴스화하는 방법은 FragmentActivity
클래스에서 제공하는 getSupportFragmentManager() 함수를 호출하는 것입니다.
FragmentManager
클래스도 public 클래스가 아닌 abstract 클래스(추상 클래스)입니다. 이 추상 클래스는 FragmentActivity
클래스에 구현되어 있기 때문에 getSupportFragmentManager()
함수를 호출해야 하는 것입니다.
FragmentManager
클래스를 인스턴스화 한 후, Activity의 onCreate() 메소드 내에서 FragmentTransaction
클래스가 제공하는 add() 함수를 호출하여 프래그먼트 컨테이너 위치에 추가하고자 할 프래그먼트 자체 UI를 추가하면 됩니다.
add() 함수는 오버로딩되어 여러 모양으로 존재하므로 상황에 적합한 add() 함수를 선택하여 호출하면 됩니다.
(위 코드 참고) if 조건문을 통해 savedInstanceState가 null일 경우에만 FragmentManager를 인스턴스화 하여 FragmentTransaction을 생성했습니다. 이렇게 하면 MainActivity가 첫 번째로 생성된 시점에만 컨테이너에 프래그먼트 자체 UI를 추가하도록 할 수 있습니다. 만약 어떠한 이유로 MainActivity가 재생성되면 더 이상 savedInstanceState가 null이 아니기 때문에 if 조건문이 실행되지 않습니다. if 조건문을 걸어주지 않을 경우, Activity가 재생성되어 Activity의 생명 주기에 의해 onCreate() 메소드가 한 번 더 호출되는 시점에 이미 추가했던 프래그먼트를 또 추가하게 됩니다.(위 코드에서 아직 언급하지 않은 코드들을 이어지는 내용과 다음 포스팅에서 다룰 예정입니다)
두 번째 방법으로 테스트해본 결과, activity_main.xml에 name 속성을 주지 않고 MainActivity의 onCreate() 메소드를 위와 같이 구현한 후 앱을 실행하니 MainActivity에 Fragment가 잘 호스팅 되었습니다.
Android Jetpack Navigation 라이브러리를 사용하여 앱의 탐색 구조를 구현한다면 FragmentManager를 직접 다뤄야 할 일이 적어져 편합니다.(Google I/O 2018 소개)
이 Navigation 라이브러리 내부 동작에 FragmentManager를 사용한 작업이 구현되어 있기 때문입니다.(개발자의 편의성 증가)
Navigation 라이브러리도 결국 내부 동작에 FragmentManager
를 사용할 만큼 프래그먼트를 사용하는 앱에서는 FragmentManager
의 사용이 빈번합니다.
그렇기 때문에 FragmentManager
가 무엇인지, 어떻게 작동하는지 파악하는 것이 중요합니다.
'프래그먼트 관리자를 인스턴스화 한다' = FragmentManager 클래스를 바탕으로 구현된 객체를 메모리에 할당해 코드에서 사용할 수 있게 한다.
런타임 시에 프래그먼트 추가/교체/삭제 작업 등을 하려면 먼저 프래그먼트 관리자 클래스를 인스턴스화 해야 합니다.(프래그먼트 관리자 클래스에 프래그먼트 추가/교체/삭제 작업을 제공하는 FragmentTransaction 이 구현되어 있기 때문이라고 위에서 언급했습니다)
프래그먼트 관리자를 인스턴스화 하는 방법은 2가지 경우에 따라 다릅니다. 2가지 경우는 'Activity 클래스에서 인스턴스화하는 경우', '프래그먼트 클래스에서 인스턴스화하는 경우' 입니다.
FragmentActivity
클래스를 상속하는 모든 서브 클래스에서 getSupportFragmentManager() 함수를 호출하면 프래그먼트 관리자를 인스턴스화할 수 있습니다.(코틀린에서는 supportFragmentManager 호출)getSupportFragmentManager()
는 FragmentActivity
클래스에서 제공하는 함수입니다.프래그먼트는 Activity에 호스팅될 수도 있지만 프래그먼트에 호스팅될 수도 있습니다.
어떤 프래그먼트가 하위 프래그먼트를 호스팅하는 경우 호스트 프래그먼트 내에서 getChildFragmentManager() 함수를 호출하여 하위 프래그먼트에 관한 프래그먼트 관리자 클래스를 인스턴스화할 수 있습니다.
하위 프래그먼트에서 호스트 프래그먼트를 관리하는 프래그먼트 관리자를 인스턴스화해야 한다면 getParentFragmentManager() 함수를 호출하면 됩니다.
getChildFragmentManager() 함수와 getParentFragmentManager() 함수는 Fragment 클래스에서 제공하는 함수입니다.
(위 그림 참고) 연두색으로 표시된 Activity는 하늘색으로 표시된 프래그먼트의 호스트 Activity입니다. 이 Activity에는 BottomNavigationView가 배치되어 있고 Home/Profile 탭 변경 시 하늘색으로 표시된 프래그먼트를 교체하여 사용자에게 앱 탐색 경험을 제공합니다.
(위 그림 참고) Example1에서 하늘색으로 표시된 프래그먼트는 하위 프래그먼트 2개를 호스팅하는 호스트 프래그먼트 입니다. 하위 프래그먼트 2개를 통해 화면을 분할하고 있습니다.(하위 프래그먼트끼리는 동위 프래그먼트라고 부릅니다)
(위 그림 참고) Example2에서 하늘색으로 표시된 프래그먼트는 ViewPager2(스와이프 뷰)를 구현하는 하위 프래그먼트 1개를 호스팅하는 호스트 프래그먼트 입니다.
Activity에서의 fragmentManager 와 supportFragmentManager 의 차이는, FragmentManager의 경우 Activity class에서 가져오고 SupportFragmentManager는 FragmentActivity에서 가져오는 것입니다. FragmentActivity 역시 Activity를 상속받지만, 상속받으면서 androidx로 마이그레이션 된다. 즉, supportFragmentManager는 androidx에서 사용하기 위한 fragmentManager입니다 Fragment에서의 fragmentManager 와 childFragmentManager 의 차이는, fragmentManager는 Activity와 Fragment 둘 다에서 관리가 가능하며, childFragmentManager는 Fragment에서만 관리가 가능합니다
(위 그림 참고) 위 예시에서 프래그먼트와 프래그먼트 관리자의 관계는 위와 같습니다. 개발자가 프래그먼트 관리자를 인스턴스화할 경우 이러한 관계를 잘 파악하고 있어야 합니다.
또한 앞서 언급한 내용 중 프래그먼트 관리자는 프래그먼트 추가/교체/삭제 작업을 제공하는 FragmentTransaction 이라는 클래스를 구현하고 있다고 언급했습니다.
(위 코드 참고) supportFragmentManager(=getSupportFragmentManager())를 호출하여 프래그먼트 관리자 클래스를 인스턴스하고 commit { } 블록을 호출한 코드입니다.
(위 코드 참고) commit{ } 블록 안에 프래그먼트 추가/교체/삭제 작업을 명시하면 됩니다(commit과 관련된 내용은 이어지는 다음 포스팅에서 다룰 예정입니다)
프래그먼트 관리자가 제공하는 findFragmentById() 함수를 사용하면 프래그먼트 컨테이너 내의 현재 프래그먼트 참조를 가져올 수 있습니다.
또는 프래그먼트에 고유한 태그를 부여한 후 findFragmentByTag() 함수를 호출하여 해당 태그가 부여된 프래그먼트 참조를 가져올 수 있습니다.
findFragmentById()는 UI를 제공하는 프래그먼트를 참조할 때 사용하고 findFragmentByTag()는 UI를 제공하지 않는 프래그먼트를 참조할 때 사용합니다.
일반적으로 안드로이드 앱은 단일 또는 소수의 Activity로 구성하는 것이 좋습니다.
주로 Activity에는 최상위 탐색 뷰(Navigation 같은 뷰)가 배치됩니다.
이 외의 Activity를 구성하는 개별 UI은 프래그먼트를 사용하여 구현합니다.
여러 프래그먼트를 한 번에 하나의 Activity에 표시하려면(분할 뷰) 대상 프래그먼트와 하위 프래그먼트를 사용해야 합니다.
(위 그림 참고) 하늘색으로 표시된 부분이 대상 프래그먼트이고 하얀색으로 표시된 부분이 대상 프래그먼트의 하위 프래그먼트 2개입니다.(하위 프래그먼트끼리는 동위 프래그먼트입니다)
특정 시점에서 프래그먼트 백 스택을 제어하는데에는 프래그먼트 관리자 1개만 허용됩니다.
앱에서 여러 동위 프래그먼트를 동시에 화면에 표시하거나 하위 프래그먼트를 사용하려는 경우 프래그먼트 관리자 한 개를 지정하여 앱의 기본 탐색을 처리해야 합니다.
앱의 기본 탐색이란 다음과 같습니다.
Activity를 탐색의 가장 바깥쪽 레이어로 간주하고 하위 프래그먼트의 각 레이어를 바깥쪽 레이어 아래에 매핑합니다. 이 때 각 레이어에는 기본 탐색 프래그먼트가 하나씩 있어야 합니다. '뒤로' 이벤트가 발생하면 가장 먼저 가장 안쪽 레이어에서 탐색 동작을 컨트롤합니다. '뒤로' 이벤트가 발생했을 때 가장 안쪽 레이어에 다시 표시할 프래그먼트 트랜잭션이 더 이상 없으면 탐색 컨트롤은 다음 바깥 레이어로 옮겨집니다. 이 프로세스는 Activity에 도달할 때까지 반복됩니다.
프래그먼트 트랜잭션 내에서 기본 탐색 프래그먼트를 지정하려면 FragmentTransaction 클래스에서 제공하는 setPrimaryNavigationFragment() 함수를 호출하여 childFragmentManager에 기본 컨트롤이 있어야 하는 프래그먼트의 인스턴스를 전달합니다.
감사합니다 ^^