프래그먼트

Fragment Manager

 

액티비티 내의 프래그먼트를 관리하기 위해서는 FragmentManager를 사용해야 합니다. FragmentManager를 얻는 법은 액티비티에서 getSupportFragmentManager()를 호출하면 됩니다.

 

  • 액티비티 내에 존재하는 프래그먼트를 findFragmentById()로 가져오거나 (액티비티 레이아웃 내에서 UI를 제공하는 프래그먼트의 경우) 또는 findFragmentByTag()로 가져옵니다.
  • popBackStack()을 사용하여 프래그먼트를 백 스택에서 꺼냅니다.
  • 백 스택에 변경 내용이 있는지 알아보기 위해 addOnBackStackChangedListener()로 리스너를 등록합니다.
  • beginTransaction()을 이용하여 FragmentTransaction을 가져올 수 있습니다.
val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()

val fragment = ExampleFragment()
fragmentTransaction.add(R.id.fragment_container, fragment, "example")
fragmentTransaction.commit()

 

 

Fragment 트랜잭션

 

액티비티에 커밋한 변경사항의 집합을 트랜잭션이라고 합니다. 트랜잭션을 이용하려면 FragmentTransaction내의 API를 사용하면 됩니다. 해당 액티비티가 관리하는 백 스택에 각 트랜잭션을 저장할 수도 있습니다. (addToBackStack) 

 

각 트랜잭션은 동시에 수행하고자 하는 변경사항의 집합입니다. 주어진 트랜잭션에 대해 수행하고자 하는 모든 변경사항을 설정하려면 add(), remove(), replace()와 같은 메서드를 사용하면 됩니다. 그런 다음 트랜잭션을 액티비티에 적용하려면 반드시 commit()을 호출해야 합니다.

 

commit()을 호출하기 전에 addToBackStack()을 호출해야 합니다. 이렇게 해야 트랜잭션을 프래그먼트 트랜잭션의 백 스택에 추가할 수 있습니다. 이 백스택은 액티비티가 관리하고, 사용자가 Back 버튼을 누르면 이를 통해 이전 프래그먼트 상태로 되돌아갈 수 있습니다.

 

commit()은 액티비티가 state를 save하기 전에 이루어져야 합니다. state save 후에 commit()이 불린다면 exception이 발생합니다.  state save와 관계 없이 commit()을 수행하려면 commitAllowingStateLoss()를 호출해줘야 합니다.

 

UncaughtException: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

 

 

val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()

val newFragment = ExampleFragment()
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragment_container, newFragment)
transaction.addToBackStack(null)
transaction.commit()

 

Fragment Lifecycle

 

 

Resumed

 

프래그먼트가 실행 중인 액티비티에 표시됩니다.

 

Paused

 

다른 액티비티가 포그라운드에 있고 포커스를 갖고 있지만, 이 프래그먼트가 있는 액티비티도 여전히 표시됩니다. (포그라운드의 액티비티가 부분적으로 투명하거나 전체 화면을 뒤덮지 않습니다.)

 

Stopped

 

프래그먼트가 보이지 않습니다. 호스트 액티비티가 정지되었거나 프래그먼트가 액티비티에서 제거되었지만 백 스택에 추가되었습니다. 모든 상태 및 멤버 정보를 시스템이 보존합니다. 하지만 사용자에게는 더 이상 표시되지 않으며 액티비티를 종료하면 이것도 종료됩니다.

 

 

onAttach()

 

프래그먼트가 처음 액티비티에 붙을 때 호출 되는 함수

 

onCreate()

 

프래그먼트를 생성 할 때 시스템에서 호출합니다. 프래그먼트가 일시정지되거나 중단되었다가 재개되었을 때 유지하고자 하는 것을 초기화 해야 합니다.

 

onCreateView()

 

프래그먼트에 대해 레이아웃을 제공하려면 반드시 onCreateView() 콜백 메서드를 구현해야 합니다. 이 메서드는 프래그먼트 루트 레이아웃(View)를 리턴해야 합니다.

 

XML로 정의된 레이아웃 리소스를 inflate 시켜야 합니다. 이를 돕기 위해 onCreateView()가 LayoutInflater 객체를 제공합니다.

 

class ExampleFragment : Fragment() {

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.example_fragment, container, false)
    }
}

 

onCreateView()로 전달된 container 매개변수가 상위 ViewGroup이며, 이 안에 프래그먼트 레이아웃이 삽입됩니다. 아래와 같이 fragmentTransaction에 프래그먼트를 add 시킬 때 전달 해 주는 R.id.fragment_container이 onCreateView의 container가 됩니다.

val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()

val fragment = ExampleFragment()
fragmentTransaction.add(R.id.fragment_container, fragment)
fragmentTransaction.commit()

 

inflate() 메서드는 다음과 같은 세 개의 인수를 가집니다.

 

  • inflate하고자 하는 레이아웃의 리소스 ID
  • inflate된 레이아웃을 포함 할 ViewGroup. container를 전달해야 시스템이 레이아웃을 inflate 시킨 후 루트 뷰에 적용 할 수 있습니다.
  • 레이아웃이 inflate 된 후 이것을 container에 첨부 시킬 지를 나타내는 부울 값 입니다. true이면 container에 inflater 된 레이아웃을 삽입하고 false면 삽입하지 않습니다.

onActivityCreated()

 

Activity에서 Fragment를 모두 생성한 다음에 호출됩니다. 여기서 부터 UI 변경 작업이 가능합니다.

댓글



Designed by JB FACTORY