프래그먼트 관리
액티비티 내의 프래그먼트를 관리하려면 FragmentManager
를 사용해야 합니다. 이것을 가져오려면 액티비티에서 getFragmentManager()
를 호출하세요.
FragmentManager
를 가지고 할 수 있는 여러 가지 일 중에 예를 들면 다음과 같습니다.
- 액티비티 내에 존재하는 프래그먼트를
findFragmentById()
로 가져오기(액티비티 레이아웃 내에서 UI를 제공하는 프래그먼트의 경우) 또는findFragmentByTag()
로 가져오기(UI를 제공하거나 하지 않는 프래그먼트의 경우). popBackStack()
을 사용하여 프래그먼트를 백 스택에서 꺼냅니다(사용자가 Back 명령을 시뮬레이션).- 백 스택에 변경 내용이 있는지 알아보기 위해
addOnBackStackChangedListener()
로 리스너를 등록합니다.
이와 같은 메서드와 그 외 다른 메서드에 대한 자세한 정보는 FragmentManager
클래스 관련 문서를 참조하세요.
이전 섹션에서 설명한 바와 같이 FragmentManager
를 사용해서도 FragmentTransaction
을 열 수 있습니다. 이렇게 하면 프래그먼트 추가 및 제거 등 트랜잭션을 수행할 수 있게 해줍니다.
프래그먼트 트랜잭션 수행
액티비티에서 프래그먼트를 사용하는 경우 특히 유용한 점은 사용자 상호작용에 응답하여 추가, 제거, 교체 및 다른 작업을 수행할 수 있다는 것입니다. 액티비티에 커밋한 변경 내용의 집합을 트랜잭션이라고 하며, 이것을 수행하려면 FragmentTransaction
내의 API를 사용하면 됩니다. 해당 액티비티가 관리하는 백 스택에 행해진 각 트랜잭션을 저장할 수도 있습니다. 이렇게 하면 사용자가 프래그먼트 변경 내역을 거쳐 뒤로 탐색할 수 있습니다(액티비티를 통과해 뒤로 탐색하는 것과 비슷합니다).
FragmentTransaction
의 인스턴스를 FragmentManager
로부터 가져오는 방법은 다음과 같습니다.
FragmentManager fragmentManager =getFragmentManager()
;
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction()
;
각 트랜잭션은 동시에 수행하고자 하는 변경 집합입니다. 주어진 트랜잭션에 대해 수행하고자 하는 모든 변경 사항을 설정하려면 add()
, remove()
, 및 replace()
와 같은 메서드를 사용하면 됩니다. 그런 다음, 트랜잭션을 액티비티에 적용하려면 반드시 commit()
을 호출해야 합니다.
하지만 commit()
을 호출하기 전에 먼저 호출해야 할 것이 있습니다. 바로 addToBackStack()
입니다. 이렇게 해야 트랜잭션을 프래그먼트 트랜잭션의 백 스택에 추가할 수 있습니다. 이 백 스택을 액티비티가 관리하며, 이를 통해 사용자가 이전 프래그먼트 상태로 되돌아갈 수 있습니다. 이때 Back 버튼을 누르면 됩니다.
예를 들어 다음은 한 프래그먼트를 다른 것으로 교체하고 이전 상태를 백 스택에 보존하는 방법을 보여줍니다.
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
이 예시에서는 newFragment
가 현재 레이아웃 컨테이너에서 식별된 프래그먼트(있는 경우)를 R.id.fragment_container
ID로 교체합니다. addToBackStack()
를 호출함으로써 교체 트랜잭션이 백 스택에 저장되므로, 사용자가 Back 버튼을 눌러 트랜잭션을 되돌리고 이전 프래그먼트를 다시 가져올 수 있습니다.
트랜잭션에 여러 개의 변경을 추가하고(예: 또 다른 add()
또는 remove()
), addToBackStack()
을 호출하면, commit()
을 호출하기 전에 적용된 모든 변경 내용이 백 스택에 하나의 트랜잭션으로 추가되며, Back 버튼을 누르면 모두 한꺼번에 되돌려집니다.
FragmentTransaction
에 변경 내용을 추가하는 순서는 중요하지 않습니다. 다만 다음과 같은 예외가 있습니다.
commit()
을 마지막으로 호출해야 합니다.- 같은 컨테이너에 여러 개의 프래그먼트를 추가하는 경우, 이를 추가하는 순서가 이들이 뷰 계층에 나타나는 순서를 결정 짓습니다.
프래그먼트를 제거하는 트랜잭션을 수행하면서 addToBackStack()
을 호출하지 않는 경우, 해당 프래그먼트는 트랜잭션이 적용되면 소멸되고 사용자가 이를 되짚어 탐색할 수 없게 됩니다. 반면에 프래그먼트를 제거하면서 addToBackStack()
을 호출하면, 해당 프래그먼트는 중단되고 사용자가 뒤로 탐색하면 재개됩니다.
팁: 각 프래그먼트 트랜잭션에 대해 전환 애니메이션을 적용하려면 커밋하기 전에 setTransition()
을 호출하면 됩니다.
commit()
을 호출해도 그 즉시 트랜잭션을 수행하지는 않습니다. 그보다는, 액티비티의 UI 스레드("주요" 스레드)를 스레드가 할 수 있는 한 빨리 이 트랜잭션을 수행하도록 일정을 예약하는 것에 가깝습니다. 하지만 필요한 경우 UI 스레드로부터 executePendingTransactions()
를 호출하면 commit()
이 제출한 트랜잭션을 즉시 실행할 수 있습니다. 트랜잭션이 다른 스레드의 작업에 대한 종속성이 아니라면 굳이 이렇게 해야만 하는 것은 아닙니다.
주의: 트랜잭션을 커밋할 때 commit()
을 사용해도 되는 것은 (사용자가 액티비티를 떠날 때) 액티비티가 그 상태를 저장하기 전뿐입니다. 그 시점 이후에 적용하려고 하면 예외가 발생합니다. 이것은 액티비티를 복원해야 하는 경우 적용 이후의 상태가 손실될 수 있기 때문입니다. 커밋이 손실되어도 괜찮은 상황이라면, commitAllowingStateLoss()
를 사용하세요.
'Programming > Android' 카테고리의 다른 글
Fragment - 5. Fragment 수명 주기 처리+ (0) | 2017.02.15 |
---|---|
Fragment - 4. 액티비티와의 통신 (0) | 2017.02.15 |
Fragment - 2. 사용 (0) | 2017.02.15 |
Fragment - 1. 서론 (0) | 2017.02.15 |
[Android] 안드로이드 Activity와 Activity Life Cycle (0) | 2016.06.22 |