[안드로이드] Fragment(프래그먼트) 와 Fragment Manager

2023. 5. 8. 08:32· Android
목차
  1. Fragment 란?
  2. Fragment Manager

Fragment 란?

테블릿처럼 큰 화면에서 기존엔 Activity 두개를 띄우거나 했지만 서로 다른 생명주기를 가져서 관리가 힘들었다..!! 

그래서, 동일한 액티비티 생명주기를 공유하지만 화면을 서로 다르게 사용하기 위해 Fragment 가 탄생했다.

 

Fragment 는 FragmentActivity 내의 어떤 동작 또는 사용자 인터페이스 일부를 나타낸다. 

 

Activity 와 결합하여 창이 여러개인 UI 를 빌드할 수 있으며 하나의 Fragment 여러 Activity 에서  재사용할 수 있다.

자체적인 생명 주기를 가지며 자체 입력 이벤트를 수신하고 Activity 실행 중에 추가 및 삭제가 가능하다.

 

 

Fragment 는 항상 액티비티 내에서 호스팅되어야 하며 액티비티의 생명 주기에 직접적인 영향을 받는다!

  • 액티비티 가 Paused -> 모든 프래그먼트도 Paused
  • 액티비티가 Destoryed -> 모든 프래그먼트도 Destroyed

 

그러나! 액티비티가 실행 중인 동안 프래그먼트를 추가, 제거하는 등 개별적 조작이 가능하다. 

이러한 조작을 프래그먼트 트랜잭션이라고 한다. 

 

트랜잭션을 수행할 때 액티비티가 관리하는 백스택에도 추가할 수 있다.

백스택을 사용하면 사용자가 트랜잭션 을 거꾸로 돌리는 것도 가능하다.

 

Fragment 를 액티비티 레이아웃에 추가하면 해당 프래그먼트는 액티비티 View 계층 내에서 ViewGroup 에 들어가고 자체적인 뷰 레이아웃을 정의한다. ViewGroup 에 추가하거나 액티비티 레이아웃 파일에서 선언하면 액티비티 레이아웃에 삽입할 수 있다.

 

장점

  • 액티비티에 종속적인 생명주기를 따르므로 부분 화면 관리에 용이함
  • 시스템 개입이 없으므로 액티비티 사용시 보다 화면 전환의 부담이 적음
  • 재활용 가능

Fragment Manager

프래그먼트를 추가, 삭제 또는 교체하고 백스택에 추가하는 등의 작업을 실행하는 클래스

 

* Jetpack Navigation 라이브러리를 사용하는 경우 FragmentManager 와 상호작용은 거의 필요하지 않음.

그러나 개발자가 알고 쓰는 것이 중요!

 

1. FragmentManager  에 엑세스

 

  • Activity 에서 액세스
    모든 FragmentActivity 및 그 서브클래스(ex: AppCompatActivity) 는 getSupportFragmentManager() 로 액세스 가능

  • 프래그먼트는 하위 프래그먼트를 하나 이상 호스팅할 수 있다.
    getChildFragmentManager() 를 통해 프래그먼트 하위 요소를 관리하는 FragmentManager 를 참조할 수 있다.
    호스트 FragmentManager 에 액세스 하려면 getParentFragmentManager() 사용

FragmentManager 참조가 있으면 이를 사용하여 사용자에게 표시되는 프래그먼트를 조작할 수 있다.

 

2. 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)
    }
}

 

위 방법 이외에도 동반 객체를 사용하여 프래그먼트 내에서 인자를 전달할 수 있다.

 

- 출처

https://developer.android.com/guide/fragments/fragmentmanager

 

프래그먼트 관리자  |  Android 개발자  |  Android Developers

프래그먼트 관리자 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 참고: Navigation 라이브러리를 사용하여 앱의 탐색을 관리하는 것이 좋습니다. 프레임워크

developer.android.com

 

저작자표시 (새창열림)

'Android' 카테고리의 다른 글

[안드로이드] Flow 공식문서로 이해하기 - 1차 Flow 기초  (0) 2023.08.25
[안드로이드] ViewModel 테스트하기 : [우아한테크코스 5기 AN_베르]  (0) 2023.07.22
[안드로이드] Fragment Lifecycle (프래그먼트 생명 주기)  (0) 2023.05.30
[안드로이드] Room Local DB  (0) 2023.05.22
[안드로이드] Activity LifeCycle  (0) 2023.05.01
  1. Fragment 란?
  2. Fragment Manager
'Android' 카테고리의 다른 글
  • [안드로이드] ViewModel 테스트하기 : [우아한테크코스 5기 AN_베르]
  • [안드로이드] Fragment Lifecycle (프래그먼트 생명 주기)
  • [안드로이드] Room Local DB
  • [안드로이드] Activity LifeCycle
베르_최성훈
베르_최성훈
베르_최성훈
베르의 안드로이드
베르_최성훈
전체
오늘
어제
  • 분류 전체보기 (57)
    • 우아한테크코스 (15)
    • Android (19)
    • kotlin (2)
    • 회고 (5)
    • Bug Fix (2)
    • 알고리즘 (6)
    • 기타 (1)
    • Jetpack Compose (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 페스타고
  • 우아한테크코스
  • SharedFlow
  • Android
  • 안드로이드
  • MVVM
  • flow
  • 프래그먼트
  • FRAGMENT
  • PRESENTER
  • Lifecycle
  • 회고
  • ViewModel
  • Kotlin
  • 우테코
  • 코틀린
  • 생명주기
  • coroutine
  • Test
  • MVP

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
베르_최성훈
[안드로이드] Fragment(프래그먼트) 와 Fragment Manager
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.