안드로이드 Fragment 주무르기

|

안드로이드 API Level 11 (허니콤) 부터 지원되기 시작한 Fragment는 얼핏 보면 layout include와 비슷해 보이지만,

자체적으로 생명주기를 갖고 있다는것이 가장 큰 차이점이다.


레퍼런스에 설명된 내용이 부족한 것 같아, 테스트 앱을 통해 여러 상황을 테스트해보았다.


Fragment의 API는 http://developer.android.com/reference/android/app/FragmentManager.html 이곳에 있으며,

가이드 문서는 http://developer.android.com/guide/components/fragments.html 에서 볼 수 있다. (물론 영어)


Fragment의 전환은 FragmentTransaction 클래스를 이용하는데,

이 트랜지션 클래스의 동작과 BackStack이라는, 그것의 정체가 궁금했다.


일단 기본적으로, Fragment가 Activity의 View에 올라가면,

onAttach -> onCreate -> onCreateView -> onCreateAnimator -> onViewCreated -> onActivityCreated -> onStart -> onResume

의 흐름을 타고,


Activity에서 제거가 된다면,

onPause -> onStop -> onDestroyView -> onCreateAnimator -> onDestroy -> onDetach 의 순으로 호출이 된다.


create/destroy는 말 그대로 생성/소멸이고,

attach/detach가 있는데, 이는 Activity에 "포함"되는 과정을 일컫는듯 싶다.

onCreateAnimator는 전환 애니메이션 효과를 위한 과정인듯 싶고.



FragmentTransaction에는 Fragment를 Activity에 올리기 위해 add와 replace의 두가지 메소드가 존재한다.


add()는 기존 Fragment를 그대로 둔 채 (onStop도 호출되지 않음) 새로운 Fragment를 올리게 된다.

올리는 시점에서 그 전에 올라가있는 Fragment에는 아무련 영향이 없다.

* 참고 : 추가된 Fragment는 액티비티가 바로 죽는 경우 (BackStack 추가 없이 Back키) onDetach()가 호출이 되지 않는 경우가 있다. 주의.


replace()는 기존 Fragment를 detach까지 끝낸 다음 새로운 Fragment를 올리는 것이 차이점이다.


하지만, replace()시에도 해당 트랜지션에 대해 백스택을 남겨놓도록 설정을 하면 detach까지는 되지 않으며, onDestroyView()까지만 처리된다.



여기서 한가지 짚고 넘어가야 할 것이 BackStack이라는 녀석이다.

처음에 이해하기를, Back키로 되돌아 갈 수 있는 Fragment 의 목록- 이라고 이해를 했었는데,

이건 Fragment를 View와 같은 개념으로 생각했던 것이고, 표면적으로 그대로 말해서

"beginTransition부터 commit까지의 전환" 자체를 저장하고 있는 녀석이다.


add/replace뿐만 아니라 hide/show등의 처리도 Back키로 복귀가 가능한 녀석인거다.

BackStack의 현재 카운트는 FragmentManager.getBackStackCount()로 가져올 수 있다.


트랜지션의 add()가 기존에 들어가있는 Fragment를 그대로 두고 새로이 추가를 하는거지만,

트랜지션에 addToBackStack()을 해주지 않으면 Back시 그냥 액티비티만 종료될 뿐이다.



FragmentManager에 popBackStack~ 메소드가 여러개 있는데,

메소드명 그대로 BackStack을 하나씩 pop하는 메소드이며, 이는 비동기적으로 이루어진다.

(콜 전에 BackStackCount나 콜 바로 후 BackStackCount는 같다는 말)


이를 동기식으로 처리하려면 Immediate postfix가 붙은 메소드로 호출을 하면 된다.


하지만 UI가 복잡한(무거운) fragment에 대해서도 괜찮은 속도가 나올지는 좀 더 테스트를 해봐야 할 듯 싶다.







액티비티와의 관계에서 어떻게 동작할지는 여러 상황에서 시도를 해 봐야 확실해지겠.........



And