본문으로 바로가기


안녕하세요. PEACE-입니다.

안드로이드 스터디 [스무 번째] 글입니다.


티비티와 생애주기에 관한 포스팅 주소 

http://mailmail.tistory.com/29



아래 내용과 사진의 일부는 Android developers API guide를 참조했습니다. 

Android developers API guide 

      https://developer.android.com/guide/components/fragments.html


1. 프래그먼트(Fragment)


프래그먼트는 액티비티 내에서 사용자 인터페이스의 일부로 구현될 수 있습니다. 하위 액티비티와 같은 개념으로 볼 수 있으며, 자체적으로 뷰와 이벤트를 가집니다. 하나의 액티비티 안에는 여러개의 프래그먼트가 구성될 수 있습니다. 


프래그먼트는 트랜잭션을 수행할 때에는 액티비티가 관리하는 백 스택에도 추가할 수 있습니다. 이 백 스택을 사용하면 사용자가 프래그먼트 트랜잭션을 거꾸로 돌릴 수 있습니다. 이는 Back 버튼을 통해 뒤로가기하여 이전 상태를 불러오는 것을 말합니다.


프래그먼트는 액티비티처럼 자신만의 생애주기를 가지고있습니다. 하지만 프래그먼트는 액티비티 내에서 구성돼있으므로 액티비티의 생애주기에 영향을 받습니다. 예를들어 프래그먼트를 담고있는 액티비티가 일시적으로 중지된 상태라면 프래그먼트 역시 중지 상태가 되고 액티비티가 소멸된다면 프래그먼트도 소멸됩니다. 하지만 액티비티가 실행 중이라면 프래그먼트는 자신의 생애주기를 개별적으로 조작할 수 있습니다. 


아래그림은 액비비티의 생애주기가 프래그먼트 생애주기에 미치는 영향에 대해 나타낸 그림입니다. 프래그먼트의 생애주기애 대한 그림은 더 아래에 있으니 참고만 하시길 바랍니다.




[그림 1] 액비비티의 생애주기가 프래그먼트 생애주기에 미치는 영향




2. 프래그먼트를 왜?


프래그먼트의 처음 도입은 Android 3.0(API Level 11)부터입니다. 태블릿과 같은 큰 화면에서 상황에 따라 화면의 일부를 사용하여 보다 유동적이고 유연한 UI 디자인을 지원하는 것이 목적이었습니다. 


아래 그림과 같이 리스트 선택에 따른 화면 변화에 적용할 수 있습니다.



[그림 2] 프래그먼트의 적용 예




3. 생애주기


프래그먼트의 생애주기는 액티비티의 생애주기와 유사합니다. 예를 들어 onCreate onStart onPause 등이 있습니다. 




[그림 3] 프래그먼트의 생애주기


프래그먼트 생애주기에 관여되는 콜백 메소드는 생각보다 많습니다. 보통은 아래처럼 최소한의 콜백 메소드만 구현합니다. 


onCreate()

시스템은 프래그먼트를 생성할 때 onCreate를 호출합니다. 프래그머너트가 일시정지되거나 중단됐다가 재개됐을때 유지하고자하는 것을 초기화하는데 활용합니다. 위의 라이프 사이클을 보면 프래그먼트 생성 시 onCreate는 처음에 한 번만 거치고 중단되어 재개될 때는 거치지 않는 것을 알 수 있습니다. 이런 점을 활용합니다.


onCreateView()

시스템은 프래그먼트가 자신의 UI를 처음 그릴 때 onCreateView를 호출합니다. 프래그먼트에 맞는 UI를 그리기 위해 메서드에서 View를 반환합니다. 또한 onCreateView는 Layout의 시작입니다. 루트라고 할 수 있습니다. 프래그먼트가 UI를 제공하지 않는 경우에는 null을 반환하면 됩니다.


onPause()

시스템이 onPause를 호출하는 것은 사용자가 프래그먼트를 떠난다는 첫 번째 신호라고 볼 수 있습니다. 하지만 이 신호가 항상 프래그먼트가 소멸되는 중이라고 보면 안됩니다. 사용자가 프래그먼트를 재개할 수 도 있기 때문입니다. 보통 onPause는 현재 사용자를 위해 유지되어야 하는 변경 사항을 커밋(저장 또는 적용)하는데 활용합니다. 


기본적으로 대부분 각 프래그먼트에 이와 같은 3개(최소한)의 콜백 메서드를 구현하지만, 프래그먼트 생애 주기의 여러 단계를 처리하려면 다른 콜백 메서드들도 사용해야합니다.




4. 액티비티에 프래그먼트 추가하는 방법


위에서 설명했듯이 프래그먼트는 보통 액티비티 UI의 일부분으로 존재합니다. 즉 액티비티의 레이아웃을 구성하는데 일부 계층으로 포함됩니다. 


레이아웃 구성

이제 호스트 액티비티에 프래그먼트를 구성하려합니다. 그렇다면 액티비티의 레이아웃에서 TextView와 같은 속성처럼 추가해주어야 합니다. 주의해야 할 것은 <fragment>안에서 android:name 이라는 특성을 지정해줘야합니다. 값은 인스턴스화(UI에 구성)할 프래그먼트의 패키지 경로를 포함하여 넣어줍니다.



액티비티 구성

액티비티가 실행 중인 동안에는 언제든지 레이아웃에 프래그먼트를 추가할 수 있습니다. 프래그먼트를 배치할 ViewGroup을 지정하기만 하면됩니다. 액티비티 내에서 프래그먼트 트랜잭션(프래그먼트 추가, 제거, 교체 등)을 수행하려면 FrangmentTransaction에서 가져온 API를 사용해야합니다. 


액티비티에서 FragmentTransaction의 인스턴스를 가져오는 방법입니다.

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

그리고 add 메서드를 사용하여 삽입할 뷰와 프래그먼트를 지정합니다.

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

FragmentTransaction을 변경하고 나면 반드시 commit 메서드를 호출하여 변경 내용을 적용시켜야합니다.




5. 프래그먼트 식별


레이아웃에 존재하는 여러 속성들은 ID를 통해 식별이 가능합니다. 프래그먼트의 D를 제공하는 데에는 세 가지 방법이 있습니다.


  • android:id 특성을 통한 고유 ID 설정.
  • android:id android:tag 특성을 통한 고유 문자열 설정.
  • 위의 두가지 중 어느 것도 제공하지 않으면, 시스템은 컨테이너 뷰의 ID를 사용한다.




6. UI가 없는 프래그먼트


위에서 UI를 제공하는 프래그먼트를 액티비티에 추가하는 방법을 봤습니다. 하지만 UI를 추가하지 않고 액티비티에 대한 백그라운드 동작을 제공하기 위해 프래그먼트를 사용할 수 있습니다.


UI없이 프래그먼트를 추가하려면 역시 add 메서드를 사용합니다. 하지만 들어가는 인자는 add(레이아웃, 프래그먼트)가 아닌 add(프래그먼트, 태그)입니다. 또한 이렇게 추가된 프래그먼트는 액티비티 레이아웃 안에 있는 뷰와 연관되어 있지 않기 때문에 onCreateView 메서드의 호출로 영향을 받지 않습니다. 따라서 onCreateView 메서드는 구현하지 않아도 됩니다.


알고있어야 할 점은 UI를 가진 프래그먼트에서는 IDTAG 둘 다 사용하여 식별이 가능하지만, UI가 없는 프래그먼트는 TAG를 통해서만 식별이 가능하다는 것입니다.