blob: 96bf7a197649d3d42d218106f655b01cba2ffe1f [file] [log] [blame]
page.title=프래그먼트
parent.title=액티비티
parent.link=activities.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2> 문서의 내용</h2>
<ol>
<li><a href="#Design">디자인 철학</a></li>
<li><a href="#Creating">프래그먼트 생성</a>
<ol>
<li><a href="#UI">사용자 인터페이스 추가하기</a></li>
<li><a href="#Adding">액티비티에 프래그먼트 추가</a></li>
</ol>
</li>
<li><a href="#Managing">프래그먼트 관리</a></li>
<li><a href="#Transactions">프래그먼트 트랜잭션 수행</a></li>
<li><a href="#CommunicatingWithActivity">액티비티와 통신</a>
<ol>
<li><a href="#EventCallbacks">액티비티로의 이벤트 콜백 생성</a></li>
<li><a href="#ActionBar">작업 모음에 항목 추가</a></li>
</ol>
</li>
<li><a href="#Lifecycle">프래그먼트 수명 주기 처리</a>
<ol>
<li><a href="#CoordinatingWithActivity">액티비티 수명 주기와 조화</a></li>
</ol>
</li>
<li><a href="#Example">예</a></li>
</ol>
<h2>Key 클래스</h2>
<ol>
<li>{@link android.app.Fragment}</li>
<li>{@link android.app.FragmentManager}</li>
<li>{@link android.app.FragmentTransaction}</li>
</ol>
<h2>참고 항목</h2>
<ol>
<li><a href="{@docRoot}training/basics/fragments/index.html">프래그먼트로 동적 UI 구축하기</a></li>
<li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">태블릿
핸드셋 지원</a></li>
</ol>
</div>
</div>
<p>{@link android.app.Fragment}는 동작 또는
{@link android.app.Activity} 내에서 사용자 인터페이스의 일부를 나타냅니다. 여러 개의 프래그먼트를 하나의 액티비티에
조합하여 창이 여러 개인 UI 구축할 있으며, 하나의 프래그먼트를 여러 액티비티에서 재사용할 있습니다. 프래그먼트는 자체 수명 주기를 가지고, 자체 입력 이벤트를 받으며,
액티비티 실행 중에 추가 제거가 가능한 액티비티의 모듈식 섹션이라고
생각하면 됩니다(다른 액티비티에
재사용할 있는 "하위 액티비티" 같은 개념).</p>
<p>프래그먼트는 항상 액티비티 내에 포함되어 있어야 하며 해당 프래그먼트의 수명 주기는
호스트 액티비티의 수명 주기에 직접적으로 영향을 받습니다. 예를 들어 액티비티가 일시정지되는 경우, 안의 모든 프래그먼트도
일시정지되며 액티비티가 소멸되면 모든 프래그먼트도 마찬가지로 소멸됩니다. 그러나 액티비티가 실행 중인
동안에는(<em>재개됨</em> <a href="{@docRoot}guide/components/activities.html#Lifecycle">수명 주기 상태</a>에 있을 때를 말합니다)
프래그먼트를 추가 또는 제거하는 개별적으로 조작할 있습니다. 그와 같은 프래그먼트 트랜잭션을
수행할 때에는 이를 액티비티가 관리하는 스택에도
추가할 있습니다. 스택 항목이 발생한 프래그먼트 트랜잭션의
기록이 됩니다. 스택을 사용하면 사용자가 프래그먼트 트랜잭션을 거꾸로 돌릴 있습니다(뒤로 이동).
이때 <em>뒤로</em> 버튼을 누르면 됩니다.</p>
<p>프래그먼트를 액티비티 레이아웃의 일부로 추가하는 경우, 이는 액티비티의 보기 계층 내부의 {@link
android.view.ViewGroup} 안에 살며, 해당 프래그먼트가 자신의 보기
레이아웃을 정의합니다.
프래그먼트를 액티비티 레이아웃에 삽입하려면 해당 프래그먼트를
액티비티의 레이아웃 파일에서 {@code &lt;fragment&gt;} 요소로 선언하거나, 애플리케이션 코드에서 이를
기존의 {@link android.view.ViewGroup}에 추가하면 됩니다. 그러나 프래그먼트가
액티비티 레이아웃의 일부분이어야만 하는 것은 아닙니다. 나름의 UI 없는 프래그먼트도 액티비티를 위한
보이지 않는 작업자로 사용할 있습니다.</p>
<p> 문서에서는 프래그먼트를 사용하도록 애플리케이션을 구축하는 법을
설명합니다. 그중에는 프래그먼트를 액티비티의 스택에 추가했을 프래그먼트가 자신의 상태를 유지하는 방법,
액티비티 액티비티 내의 다른 프래그먼트와 이벤트를 공유하는 방법과 액티비티의
작업 모음에 참가하는 등등 여러 가지가 포함됩니다.</p>
<h2 id="Design">디자인 철학</h2>
<p>Android 프래그먼트를 처음 도입한 것은 Android 3.0(API 레벨 11)부터입니다. 기본적으로
태블릿과 같은 화면에서 보다 역동적이고 유연한 UI 디자인을 지원하는 것이 목적이었습니다. 태블릿의 화면은
핸드셋 화면보다 훨씬 크기 때문에 UI 구성 요소를 조합하고 상호 교환할 공간이
많습니다. 프래그먼트는 개발자가 보기 계층에 복잡한 변경 내용을 관리하지 않아도
그러한 디자인을 사용할 있도록 해주는 것입니다. 액티비티의 레이아웃을 여러 프래그먼트로 나누면
런타임에 액티비티의 외관을 수정할 수도 있고 그러한 변경 내용을 해당 액티비티가 관리하는
스택에 보존할 수도 있습니다.</p>
<p>예를 들어 뉴스 애플리케이션이라면 하나의 프래그먼트를 사용하여
왼쪽에 기사 목록을 표시하도록 하고 다른 프래그먼트로 오른쪽에 기사 내용을 표시하도록 있습니다. 프래그먼트 모두
액티비티에서 양쪽으로 나란히 나타나며, 프래그먼트에 나름의 수명 주기 콜백 메서드가 있고
각자 사용자 입력 이벤트를 따로 처리하게 됩니다. 따라서, 사용자는 기사를 선택하는 액티비티를 쓰고
기사를 읽는 다른 액티비티를 선택하는 대신에 같은 액티비티 안에서 기사를 선택하고 읽는 과정을
모두 끝낼 있는 것입니다. 이것은 그림 1 나타낸 태블릿 레이아웃과 같습니다.</p>
<p>프래그먼트를 디자인할 때에는 프래그먼트를 모듈식이며 재사용 가능한 액티비티 구성 요소로 만들어야 합니다.
다시 말해, 프래그먼트가 나름의 레이아웃을 따로 정의하고 자기만의 수명 주기 콜백으로 자기 나름의 동작을 정의하기 때문에
프래그먼트를 여러 액티비티에 포함시킬 있습니다. 그러므로 재사용을 염두에 두고 디자인하며
프래그먼트를 다른 프래그먼트로부터 직접 조작하는 것은 삼가야 합니다. 이것은 특히 모듈식 프래그먼트를 사용하면
프래그먼트 조합을 여러 가지 화면 크기에 맞춰 변경할 있도록 해주기 때문에 중요한 요점입니다. 태블릿과 핸드셋을 모두 지원하는
애플리케이션을 디자인하는 경우, 사용 가능한 화면 공간을 토대로 사용자 경험을 최적화하도록 프래그먼트를
여러 레이아웃 구성에 재사용할 있습니다. 예를 들어 핸드셋에서의 경우
프래그먼트를 분리해서 단일 UI 제공하도록 해야할 있습니다. 같은 액티비티 안에 하나 이상이 들어가지 않을
있기 때문입니다.</p>
<img src="{@docRoot}images/fundamentals/fragments.png" alt="" />
<p class="img-caption"><strong>그림 1.</strong> 프래그먼트가 정의한 가지 UI 모듈이
태블릿 디자인에서는 하나의 액티비티로 조합될 있는 반면 핸드셋 디자인에서는 분리될 있다는 것을
예시로 나타낸 것입니다.</p>
<p>예를 들어&mdash;뉴스 애플리케이션 예시를 계속 사용하겠습니다&mdash;이 애플리케이션을 태블릿 크기의 기기에서 실행하는 경우,
애플리케이션 내의 <em>액티비티 A</em> 안에 개의 프래그먼트를 포함시킬 있습니다. 그러나
핸드셋 크기의 화면에서라면 프래그먼트를 모두 만큼 공간이 충분치 않습니다.
따라서 <em>액티비티 A</em>에는 기사 목록에 해당되는 프래그먼트만 포함하고, 사용자가 기사를 하나 선택하면 이것이
<em>액티비티 B</em>를 시작합니다. 여기에 기사를 읽을 번째 프래그먼트가 포함되어 있습니다. 따라서 애플리케이션은
서로 다른 조합으로 프래그먼트를 재사용함으로써 태블릿과 핸드셋을 지원하는
것입니다(그림 1 참조).</p>
<p>여러 가지 화면 구성에 맞게 여러 가지 프래그먼트 조합으로 애플리케이션을 디자인하는 법에 대한 자세한 정보는
<a href="{@docRoot}guide/practices/tablets-and-handsets.html">태블릿 핸드셋 지원</a>에 대한 가이드를 참조하십시오.</p>
<h2 id="Creating">프래그먼트 생성</h2>
<div class="figure" style="width:327px">
<img src="{@docRoot}images/fragment_lifecycle.png" alt="" />
<p class="img-caption"><strong>그림 2.</strong> 프래그먼트의 수명 주기(
소속 액티비티가 실행 중일 때).</p>
</div>
<p>프래그먼트를 생성하려면 {@link android.app.Fragment}의 하위 클래스(또는 이의 기존
하위 클래스)를 생성해야 합니다. {@link android.app.Fragment} 클래스에는
{@link android.app.Activity}와 아주 유사해 보이는 코드가 있습니다. 여기에는 액티비티와 비슷한 콜백 메서드가 들어 있습니다.
예를 들어 {@link android.app.Fragment#onCreate onCreate()}, {@link android.app.Fragment#onStart onStart()},
{@link android.app.Fragment#onPause onPause()} 및 {@link android.app.Fragment#onStop onStop()} 등입니다. 사실,
기존 Android 애플리케이션을 변환하여 프래그먼트를 사용하도록 하려면 그저
액티비티의 콜백 메서드에서 프래그먼트에 해당되는 콜백 메서드로 코드를 옮기기만 하면
수도 있습니다.</p>
<p>보통은 최소한 다음과 같은 수명 주기 메서드를 구현해야 합니다.</p>
<dl>
<dt>{@link android.app.Fragment#onCreate onCreate()}</dt>
<dd>시스템은 프래그먼트를 생성할 이것을 호출합니다. 구현 내에서 프래그먼트의 기본 구성 요소
프래그먼트가 일시정지되거나 중단되었다가 재개되었을 유지하고자 하는 것을
초기화해야 합니다.</dd>
<dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt>
<dd>시스템은 프래그먼트가 자신의 사용자 인터페이스를 처음으로 그릴 시간이 되면
이것을 호출합니다. 프래그먼트에 맞는 UI 그리려면 메서드에서 {@link android.view.View}를 반환해야 합니다.
메서드는 프래그먼트 레이아웃의 루트입니다. 프래그먼트가 UI 제공하지 않는 경우 null 반환하면
됩니다.</dd>
<dt>{@link android.app.Activity#onPause onPause()}</dt>
<dd>시스템이 메서드를 호출하는 것은 사용자가 프래그먼트를 떠난다는
번째 신호입니다(다만 이것이 항상 프래그먼트가 소멸 중이라는 뜻은 아닙니다). 현재 사용자 세션을 넘어서
지속되어야 하는 변경 사항을 커밋하려면 보통 이곳에서 해아 합니다(사용자가
돌아오지 않을 있기 때문입니다).</dd>
</dl>
<p>대부분의 애플리케이션은 각각의 프래그먼트에 이와 같은 메서드를 최소한 개씩
구현해야 하지만, 프래그먼트 수명 주기의 여러 단계를 처리하려면 사용해야 하는 다른 콜백 메서드도
많이 있습니다. 모든 수명 주기 콜백 메서드는 나중에
<a href="#Lifecycle">프래그먼트 수명 주기 처리</a> 섹션에서 더욱 상세히 논의할 것입니다.</p>
<p>이외에도, 기본적인 {@link
android.app.Fragment} 클래스 대신 확장하고자 하는 하위 클래스도 있을 있습니다.</p>
<dl>
<dt>{@link android.app.DialogFragment}</dt>
<dd>부동 대화 창을 표시합니다. 클래스를 사용하여 대화를 생성하면
{@link android.app.Activity} 클래스의 대화 도우미 메서드를 사용하는 것의
좋은 대안책이 됩니다. 이렇게 하면 프래그먼트 대화를 액티비티가 관리하는 프래그먼트의 스택에 통합시킬 있어,
사용자가 무시된 프래그먼트를 반환할 있도록 해주기 때문입니다.</dd>
<dt>{@link android.app.ListFragment}</dt>
<dd>어댑터가 관리하는 항목의 목록(예: {@link
android.widget.SimpleCursorAdapter})을 표시하며, {@link android.app.ListActivity}와 비슷합니다.
이것은 목록 보기를 관리하는 쓰는 가지 메서드를 제공합니다. 예를 들어 {@link
android.app.ListFragment#onListItemClick(ListView,View,int,long) onListItemClick()} 콜백을
제공하여 클릭 이벤트를 처리하는 등입니다.</dd>
<dt>{@link android.preference.PreferenceFragment}</dt>
<dd>{@link android.preference.Preference} 객체의 계층을 목록으로 표시하며,
{@link android.preference.PreferenceActivity}와 비슷합니다. 이것은
애플리케이션에 대한 "설정" 액티비티를 생성할 유용합니다.</dd>
</dl>
<h3 id="UI">사용자 인터페이스 추가하기</h3>
<p>프래그먼트는 일반적으로 액티비티에 속한 사용자 인터페이스의 일부분으로 사용되며
자기 나름의 레이아웃으로 액티비티에 참가합니다.</p>
<p>프래그먼트에 대해 레이아웃을 제공하려면 반드시 {@link
android.app.Fragment#onCreateView onCreateView()} 콜백 메서드를 구현해야 합니다.
이것은 프래그먼트가 자신의 레이아웃을 그릴 때가 되면 Android 시스템이 호출하는 것입니다. 메서드의 구현은 반드시
{@link android.view.View}를 반환해야 합니다. 이것은 프래그먼트 레이아웃의 루트입니다.</p>
<p class="note"><strong>참고:</strong> 프래그먼트가 {@link
android.app.ListFragment}의 하위 클래스인 경우, 기본 구현이
{@link android.app.Fragment#onCreateView onCreateView()}로부터 {@link android.widget.ListView}를 반환하므로 이를 구현하지 않아도 됩니다.</p>
<p>{@link
android.app.Fragment#onCreateView onCreateView()}로부터 레이아웃을 반환하려면 이를 XML에서 정의된 <a href="{@docRoot}guide/topics/resources/layout-resource.html">레이아웃 리소스</a>로부터 팽창시키면 됩니다. 이를 돕기 위해
{@link android.app.Fragment#onCreateView onCreateView()}가
{@link android.view.LayoutInflater} 객체를 제공합니다.</p>
<p>예를 들어 다음은 {@link android.app.Fragment}의 하위 클래스입니다. 이것이
{@code example_fragment.xml} 파일로부터 레이아웃을 로딩합니다.</p>
<pre>
public static class ExampleFragment extends Fragment {
&#64;Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
</pre>
<div class="sidebox-wrapper">
<div class="sidebox">
<h3>레이아웃 생성</h3>
<p>위의 샘플에서 {@code R.layout.example_fragment}는
애플리케이션 리소스에 저장된 {@code example_fragment.xml}이라는 레이아웃 리소스에 대한 참조입니다. 레이아웃을
XML 생성하는 방법에 대한 정보는 <a href="{@docRoot}guide/topics/ui/index.html">사용자 인터페이스</a>
문서를 참조하십시오.</p>
</div>
</div>
<p>{@link android.app.Fragment#onCreateView
onCreateView()}로 전달된 {@code container} 매개변수가 상위 {@link android.view.ViewGroup}이며(액티비티의 레이아웃으로부터),
안에 프래그먼트 레이아웃이 삽입됩니다.
{@code savedInstanceState} 매개변수는 일종의 {@link android.os.Bundle}로,
이것은 프래그먼트가 재개되는 중인 경우 프래그먼트의 이전 인스턴스에 대한 데이터를
제공합니다(상태를 복원하는 것은 <a href="#Lifecycle">프래그먼트 수명 주기
처리</a>에서 좀 더 논의합니다).</p>
<p>{@link android.view.LayoutInflater#inflate(int,ViewGroup,boolean) inflate()} 메서드는
다음과 같은 개의 인수를 취합니다.</p>
<ul>
<li>팽창시키고자 하는 레이아웃의 리소스 ID.</li>
<li>팽창된 레이아웃의 상위가 {@link android.view.ViewGroup}. {@code
container}를 전달해야 시스템이 레이아웃 매개변수를 팽창된 레이아웃의 루트 보기에 실행 중인 상위 보기에서 지정한 것과 같이
적용할 있으므로 이는 중요한 부분입니다.</li>
<li>팽창된 레이아웃이 팽창 중에 {@link
android.view.ViewGroup}(두 번째 매개변수)에 첨부되어야 하는지를 나타내는 부울 (이 경우,
이것은 거짓입니다. 시스템이 이미 팽창된 레이아웃을 {@code
container} 안에 삽입하고 있기 때문입니다. 참을 전달하면 최종 레이아웃에 중복된 보기 그룹을 생성하게 됩니다).</li>
</ul>
<p>이제 레이아웃을 제공하는 프래그먼트 생성하는 법을 알게 되셨습니다. 다음은 프래그먼트를
액티비티에 추가해야 합니다.</p>
<h3 id="Adding">액티비티에 프래그먼트 추가</h3>
<p>프래그먼트는 보통 UI 일부분으로 호스트 액티비티에 참가합니다. 이는 해당 액티비티의
전반적인 보기 계층의 일부분으로 포함되게 됩니다. 프래그먼트를 액티비티 레이아웃에 추가하는 데에는 가지 방법이
있습니다.</p>
<ul>
<li><b>프래그먼트를 액티비티의 레이아웃 파일 안에서 선언합니다.</b>
<p> 경우, 프래그먼트에 대한 레이아웃 속성을 마치
보기인 것처럼 나타낼 있습니다. 예를 들어 다음은 프래그먼트가 있는
액티비티에 대한 레이아웃 파일을 나타낸 것입니다.</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"&gt;
&lt;fragment android:name="com.example.news.ArticleListFragment"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" /&gt;
&lt;fragment android:name="com.example.news.ArticleReaderFragment"
android:id="@+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" /&gt;
&lt;/LinearLayout&gt;
</pre>
<p>{@code &lt;fragment&gt;} 안의 {@code android:name} 속성이 레이아웃 안에서 인스턴트화할 {@link
android.app.Fragment} 클래스를 나타냅니다.</p>
<p>시스템은 액티비티 레이아웃을 생성할 레이아웃에서 지정된 프래그먼트를 인스턴트화하며 각각에 대해
{@link android.app.Fragment#onCreateView onCreateView()} 메서드를
호출하여 프래그먼트의 레이아웃을 검색합니다. 시스템은 프래그먼트가 반환한 {@link android.view.View}를
{@code &lt;fragment&gt;} 요소 자리에 곧바로 삽입합니다.</p>
<div class="note">
<p><strong>참고:</strong> 프래그먼트에는 액티비티가 재시작되는 경우
프래그먼트를 복구하기 위해 시스템이 사용할 있는 고유한 식별자가 필요합니다(그리고, 개발자는 이것을 사용하여 프래그먼트를 캡처해
이를 제거하는 여러 가지 트랜잭션을 수행할 있습니다). 프래그먼트에 ID 제공하는 데에는
다음과 같은 가지 방법이 있습니다.</p>
<ul>
<li>고유한 ID 함께 {@code android:id} 속성을 제공합니다.</li>
<li>고유한 문자열과 함께 {@code android:tag} 속성을 제공합니다.</li>
<li>위의 가지 어느 것도 제공하지 않으면, 시스템은 컨테이너 보기의 ID
사용합니다.</li>
</ul>
</div>
</li>
<li><b>또는, 프로그래밍 방식으로 프래그먼트를 기존의 {@link android.view.ViewGroup}에 추가합니다.</b>
<p>액티비티가 실행 중인 동안에는 언제든 액티비티 레이아웃에 프래그먼트를 추가할 있습니다. 그저 프래그먼트를 배치할
{@link
android.view.ViewGroup}를 지정하기만 하면 됩니다.</p>
<p>액티비티 내에서 프래그먼트 트랜잭션을 수행하려면(프래그먼트 추가, 제거 또는
교체 등), {@link android.app.FragmentTransaction}에서 가져온 API 사용해야 합니다.
{@link android.app.FragmentTransaction}의 인스턴스를 {@link android.app.Activity}에서 가져오는 방법은 다음과 같습니다.</p>
<pre>
FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()}
FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()};
</pre>
<p>그런 다음 {@link
android.app.FragmentTransaction#add(int,Fragment) add()} 메서드를 사용하여 프래그먼트를 추가하고, 추가할 프래그먼트와 이를 삽입할
보기를 지정하면 됩니다. 예:</p>
<pre>
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
</pre>
<p>{@link android.app.FragmentTransaction#add(int,Fragment) add()}에
전달되는 인수가 {@link android.view.ViewGroup}입니다.
여기에 프래그먼트가 리소스 ID 지정한 바와 같이 배치되어야 하며, 번째 매개변수는 추가할 프래그먼트입니다.</p>
<p>
{@link android.app.FragmentTransaction}을 변경하고 나면, 반드시
{@link android.app.FragmentTransaction#commit}을 호출해야 변경 내용이 적용됩니다.</p>
</li>
</ul>
<h4 id="AddingWithoutUI">UI 없이 프래그먼트 추가</h4>
<p>위의 예시에서는 UI 제공하기 위해 프래그먼트를 액티비티에 추가하는 방법을 보여드렸습니다. 하지만
추가로 UI 제시하지 않고 액티비티에 대한 배경 동작을 제공하는 데에도 프래그먼트를 사용할
있습니다.</p>
<p>UI 없이 프래그먼트를 추가하려면 액티비티로부터 가져온 프래그먼트를 {@link
android.app.FragmentTransaction#add(Fragment,String)}을 사용하여 추가합니다(이때, 프래그먼트에 대해
보기 ID보다는 고유한 문자열 "태그" 제공합니다). 이렇게 하면 프래그먼트가 추가되지만,
이것은 액티비티 레이아웃 안에 있는 보기와 연관되어 있지 않기 때문에 {@link
android.app.Fragment#onCreateView onCreateView()}로의 호출은 받지 않습니다. 따라서 그 메서드는 구현하지 않아도 됩니다.</p>
<p>프래그먼트에 대해 문자열 태그를 제공하는 것은 엄밀히 말해 UI 프래그먼트에만 해당되는 것은 아닙니다. UI 있는
프래그먼트에도 문자열 태그를 제공할 있습니다. 하지만 프래그먼트에
UI 없는 경우라면 이를 식별할 방법은 문자열 태그뿐입니다. 액티비티에서 나중에
프래그먼트를 가져오고자 하는 경우, {@link android.app.FragmentManager#findFragmentByTag
findFragmentByTag()}를 사용해야 합니다.</p>
<p>예를 들어 어떤 액티비티에서 UI 없이 프래그먼트를 배경 작업자로 사용한다고 가정해봅시다. 이것의 예로 {@code
FragmentRetainInstance.java} 샘플을 있으며
이는 SDK 샘플에 포함되어 있고(Android SDK Manager 통해 이용 가능), 시스템에는
<code>&lt;sdk_root&gt;/APIDemos/app/src/main/java/com/example/android/apis/app/FragmentRetainInstance.java</code>로 찾을 수 있습니다.</p>
<h2 id="Managing">프래그먼트 관리</h2>
<p>액티비티 내의 프래그먼트를 관리하려면 {@link android.app.FragmentManager}를 사용해야 합니다. 이것을
가져오려면 액티비티에서 {@link android.app.Activity#getFragmentManager()}를 호출하십시오.</p>
<p>{@link android.app.FragmentManager}를 가지고 있는 여러 가지 중에 예를 들면 다음과 같습니다.</p>
<ul>
<li>액티비티 내에 존재하는 프래그먼트를 {@link
android.app.FragmentManager#findFragmentById findFragmentById()}로 가져오기(액티비티 레이아웃 내에서
UI 제공하는 프래그먼트의 경우) 또는 {@link android.app.FragmentManager#findFragmentByTag
findFragmentByTag()}로 가져오기(UI 제공하거나 하지 않는 프래그먼트의 경우).</li>
<li> 스택에서 프래그먼트를 {@link
android.app.FragmentManager#popBackStack()}을 사용하여 튀어나오게 하기(사용자가 내린 <em>뒤로</em> 명령을 시뮬레이트함).</li>
<li> 스택에 변경 내용이 있는지 알아보기 위해 {@link
android.app.FragmentManager#addOnBackStackChangedListener addOnBackStackChangedListener()}로 수신기 등록하기.</li>
</ul>
<p>이와 같은 메서드와 다른 메서드에 대한 자세한 정보는 {@link
android.app.FragmentManager} 클래스 관련 문서를 참조하십시오.</p>
<p>이전 섹션에서 설명한 바와 같이 {@link android.app.FragmentManager}를
사용해서도 {@link android.app.FragmentTransaction}
있습니다. 이렇게 하면 프래그먼트 추가 제거 트랜잭션을 수행할 있게 해줍니다.</p>
<h2 id="Transactions">프래그먼트 트랜잭션 수행</h2>
<p>액티비티에서 프래그먼트를 사용하는 경우 특히 유용한 점은 사용자 상호 작용에 응답하여 추가,
제거, 교체 다른 작업을 수행할 있다는 것입니다. 액티비티에 적용한
변경 내용의 집합을 하나의 트랜잭션이라 칭합니다. 이것을 수행하려면 {@link
android.app.FragmentTransaction} 내의 API 사용하면 됩니다. 해당 액티비티가 관리하는 스택에 행해진 트랜잭션을
저장할 수도 있습니다. 이렇게 하면 사용자가 프래그먼트 변경 내역을 거쳐 뒤로 탐색할 있습니다(액티비티를 통과해
뒤로 탐색하는 것과 비슷합니다).</p>
<p>{@link android.app.FragmentTransaction}의 인스턴스를 {@link
android.app.FragmentManager}로부터 가져오는 방법은 다음과 같습니다.</p>
<pre>
FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()};
FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()};
</pre>
<p> 트랜잭션은 동시에 수행하고자 하는 여러 변경을 집합적으로 일컫는 말입니다. 주어진
트랜잭션에 대해 수행하고자 하는 모든 변경 사항을 설정하려면 {@link
android.app.FragmentTransaction#add add()}, {@link android.app.FragmentTransaction#remove remove()},
{@link android.app.FragmentTransaction#replace replace()}와 같은 메서드를 사용하면 됩니다. 그런 다음,
트랜잭션을 액티비티에 적용하려면 반드시 {@link android.app.FragmentTransaction#commit()}을 호출해야 합니다.</p>
</dl>
<p>하지만 {@link
android.app.FragmentTransaction#commit()}을 호출하기 전에 먼저 호출해야 할 것이 있습니다. 바로 {@link
android.app.FragmentTransaction#addToBackStack addToBackStack()}입니다.
이렇게 해야 트랜잭션을 프래그먼트 트랜잭션의 스택에 추가할 있습니다. 스택을 액티비티가 관리하며,
이를 통해 사용자가 이전 프래그먼트 상태로 되돌아갈 있습니다. 이때 <em>뒤로</em> 버튼을 누르면 됩니다.</p>
<p>예를 들어 다음은 프래그먼트를 다른 것으로 교체하고 이전 상태를 스택에 보존하는 법을
나타낸 것입니다.</p>
<pre>
// 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();
</pre>
<p> 예시에서 {@code newFragment}가 현재 레이아웃 컨테이너에 있는
프래그먼트(있는 경우)를 교체합니다. 이는 {@code R.id.fragment_container} ID 식별할 있습니다. {@link
android.app.FragmentTransaction#addToBackStack addToBackStack()}를 호출하면 교체 트랜잭션이
스택에 저장되고, 따라서 사용자가 트랜잭션을 거꾸로 수행하여
이전 프래그먼트를 도로 가져올 있습니다. <em>뒤로</em> 버튼을 사용하면 됩니다.</p>
<p>트랜잭션에 여러 개의 변경을 추가하고(예를 들어 다른 {@link
android.app.FragmentTransaction#add add()} 또는 {@link android.app.FragmentTransaction#remove
remove()}) {@link
android.app.FragmentTransaction#addToBackStack addToBackStack()}을 호출하면, {@link android.app.FragmentTransaction#commit commit()}을 호출하기 전에 적용된 모든 변경 내용이
스택에 하나의 트랜잭션으로 추가되며, <em>뒤로</em> 버튼을 누르면
모두 한꺼번에 역행하게 됩니다.</p>
<p>{@link android.app.FragmentTransaction}에 변경 내용을 추가하는 순서는 중요하지 않습니다.
다만 다음과 같은 예외가 있습니다.</p>
<ul>
<li>{@link android.app.FragmentTransaction#commit()}을 마지막으로 호출해야만 합니다.</li>
<li>같은 컨테이너에 여러 개의 프래그먼트를 추가하는 경우, 이를 추가하는 순서가 이들이
보기 계층에 나타나는 순서를 결정 짓습니다.</li>
</ul>
<p>프래그먼트를 제거하는 트랜잭션을 수행하면서 {@link android.app.FragmentTransaction#addToBackStack(String)
addToBackStack()}을 호출하지 않는 경우,
해당 프래그먼트는 트랜잭션이 적용되면 소멸되고 사용자가 이를 되짚어 탐색할 없게 됩니다. 반면에
프래그먼트를 제거하면서 {@link android.app.FragmentTransaction#addToBackStack(String) addToBackStack()}을 호출하면,
해당 프래그먼트는 <em>중단</em>되고 사용자가 뒤로 탐색하면
재개됩니다.</p>
<p class="note"><strong>팁:</strong> 프래그먼트 트랜잭션에 대해 전환 애니메이션을 적용하려면
커밋하기 전에 {@link android.app.FragmentTransaction#setTransition setTransition()}을
호출하면 됩니다.</p>
<p>{@link android.app.FragmentTransaction#commit()}을 호출해도 그 즉시 트랜잭션을 수행하지는
않습니다. 그보다는, 액티비티의 UI 스레드("주요" 스레드)를 스레드가 있는 빨리
트랜잭션을 수행하도록 일정을 예약하는 것에 가깝습니다. 하지만 필요한 경우 UI 스레드로부터 {@link
android.app.FragmentManager#executePendingTransactions()}를 호출하면
{@link android.app.FragmentTransaction#commit()}이 제출한 트랜잭션을 즉시 실행할 수 있습니다. 트랜잭션이
다른 스레드의 작업에 대한 종속성이 아니라면 굳이 이렇게 해야만 하는 것은 아닙니다.</p>
<p class="caution"><strong>주의:</strong> 트랜잭션을 적용할 {@link
android.app.FragmentTransaction#commit commit()}을 사용해도 되는 것은 액티비티가 <a href="{@docRoot}guide/components/activities.html#SavingActivityState">그 상태를
저장</a>하기 전뿐입니다(사용자가 액티비티를 떠날 때). 시점 이후에 적용하려고 하면 예외가
발생합니다. 이것은 액티비티를 복원해야 하는 경우 적용 이후의 상태가 손실될
있기 때문입니다. 적용이 손실되어도 괜찮은 상황이라면, {@link
android.app.FragmentTransaction#commitAllowingStateLoss()}를 사용하십시오.</p>
<h2 id="CommunicatingWithActivity">액티비티와 통신</h2>
<p>{@link android.app.Fragment}는
{@link android.app.Activity}로부터 독립적인 객체로 구현되었고 여러 개의 액티비티 안에서 사용할 있는 것이 사실이지만,
프래그먼트의 주어진 인스턴스는 그것을 포함하고 있는 액티비티에 직접적으로 연결되어 있습니다.</p>
<p>구체적으로 말하면, 프래그먼트는 {@link
android.app.Fragment#getActivity()}를 사용하여 {@link android.app.Activity} 인스턴스에 액세스하여
액티비티 레이아웃에서 보기를 찾는 것과 같은 작업을 손쉽게 수행할 있습니다.</p>
<pre>
View listView = {@link android.app.Fragment#getActivity()}.{@link android.app.Activity#findViewById findViewById}(R.id.list);
</pre>
<p>이와 마찬가지로, 액티비티도 프래그먼트 안의 메서드를 호출할 있습니다. 그러려면 {@link android.app.FragmentManager}로부터의
{@link android.app.Fragment}에 대한 참조를 가져와야 하며, 이때 {@link
android.app.FragmentManager#findFragmentById findFragmentById()} 또는 {@link
android.app.FragmentManager#findFragmentByTag findFragmentByTag()}를 사용합니다. 예:</p>
<pre>
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
</pre>
<h3 id="EventCallbacks">액티비티로의 이벤트 콜백 생성</h3>
<p>어떤 경우에는 프래그먼트로 하여금 액티비티와 이벤트를 공유하게 해야 있습니다. 이렇게 하기 위한
가지 좋은 방법은 프래그먼트 내부의 콜백 인터페이스를 정의한 다음 해당 호스트 액티비티가 이를 구현하도록
하는 것입니다. 액티비티가 인터페이스를 통해 콜백을 수신하면, 필요에 따라 정보를 레이아웃 내의
다른 프래그먼트와 공유할 있습니다.</p>
<p>예를 들어 어떤 뉴스 애플리케이션에서 액티비티 하나에 프래그먼트가 있습니다.
하나는 기사 목록을 표시(프래그먼트 A)하고 다른 하나는 기사 하나를 표시(프래그먼트 B)하는 경우 목록 항목이 선택되면
프래그먼트 A 액티비티에 알려야 프래그먼트 B 해당 기사를 표시하라고 알릴 있습니다. 경우,
{@code OnArticleSelectedListener} 인터페이스는 프래그먼트 A 내부에 선언됩니다.</p>
<pre>
public static class FragmentA extends ListFragment {
...
// Container Activity must implement this interface
public interface OnArticleSelectedListener {
public void onArticleSelected(Uri articleUri);
}
...
}
</pre>
<p>그러면 프래그먼트를 호스팅하는 액티비티가 {@code OnArticleSelectedListener}
인터페이스를
구현하고 {@code onArticleSelected()}를 재정의하여 프래그먼트 A로부터 일어난 이벤트를
프래그먼트 B 알립니다. 호스트 액티비티가 인터페이스를 구현하도록
확실히 하려면 프래그먼트 A {@link
android.app.Fragment#onAttach onAttach()} 콜백 메서드(프래그먼트를 액티비티에 추가할 때 시스템이 호출하는 것)가 {@code OnArticleSelectedListener}의 인스턴스를 인스턴트화해야 합니다. 이때 {@link android.app.Fragment#onAttach
onAttach()} 안으로 전달된 {@link android.app.Activity}를
캐스팅하는 방법을 씁니다.</p>
<pre>
public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
...
&#64;Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnArticleSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
}
}
...
}
</pre>
<p>액티비티가 인터페이스를 구현하지 않은 경우, 프래그먼트가
{@link java.lang.ClassCastException}을 발생시킵니다.
성공 시, {@code mListener} 구성원이 액티비티의
{@code OnArticleSelectedListener} 구현에 대한 참조를 보유하므로, 프래그먼트 A 액티비티와 이벤트를 공유할 있습니다.
이때 {@code OnArticleSelectedListener} 인터페이스가 정의한 메서드를 호출하는 방법을 씁니다. 예를 들어 프래그먼트 A
{@link android.app.ListFragment}의 확장인 경우,
사용자가 목록 항목을 클릭할 때마다 시스템이 프래그먼트 안의 {@link android.app.ListFragment#onListItemClick
onListItemClick()}을 호출하고, 그러면 이것이 {@code onArticleSelected()}를 호출하여
해당 이벤트를 액티비티와 공유하는 것입니다.</p>
<pre>
public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
...
&#64;Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Append the clicked item's row ID with the content provider Uri
Uri noteUri = ContentUris.{@link android.content.ContentUris#withAppendedId withAppendedId}(ArticleColumns.CONTENT_URI, id);
// Send the event and Uri to the host activity
mListener.onArticleSelected(noteUri);
}
...
}
</pre>
<p>{@link
android.app.ListFragment#onListItemClick onListItemClick()}에 전달된 {@code id} 매개변수가 클릭한 항목의 행 ID이며,
액티비티(또는 다른 프래그먼트)가 이것을 사용해 애플리케이션의 {@link
android.content.ContentProvider}에서 기사를 가져옵니다.</p>
<p><!--To see a complete implementation of this kind of callback interface, see the <a
href="{@docRoot}resources/samples/NotePad/index.html">NotePad sample</a>. -->콘텐츠 제공자 사용법에 대한 자세한 정보는
<a href="{@docRoot}guide/topics/providers/content-providers.html">콘텐츠 제공자</a> 문서에서 이용하실 수 있습니다.</p>
<h3 id="ActionBar">작업 모음에 항목 추가</h3>
<p>프래그먼트는 액티비티의 <a href="{@docRoot}guide/topics/ui/menus.html#options-menu">옵션 메뉴</a>에(결과적으로 <a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a>에도) 메뉴 항목으로 참가할 수 있습니다. 이때
{@link android.app.Fragment#onCreateOptionsMenu(Menu,MenuInflater) onCreateOptionsMenu()}를 구현하는 방법을 씁니다. 이 메서드가
호출을 수신하도록 하려면, {@link
android.app.Fragment#onCreate(Bundle) onCreate()} 중에 {@link
android.app.Fragment#setHasOptionsMenu(boolean) setHasOptionsMenu()}를 호출하여 프래그먼트가
옵션 메뉴에 항목을 추가하고자 한다는 것을 나타내야 합니다(그렇지 않으면 해당 프래그먼트가
{@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()}로의 호출을 받지 못하게 됩니다).</p>
<p>그런 다음 프래그먼트로부터 옵션 메뉴에 추가하는 모든 항목은 기존의 메뉴 항목에
추가됩니다. 해당 프래그먼트는 메뉴 항목을 선택하면 {@link
android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}로의 콜백도
수신하게 됩니다.</p>
<p>또한 프래그먼트 레이아웃에 보기를 등록하여 컨텍스트 메뉴를 제공하도록 할 수도 있습니다. 이때 {@link
android.app.Fragment#registerForContextMenu(View) registerForContextMenu()}를 호출하면 됩니다. 사용자가 컨텍스트 메뉴를 열면,
해당 프래그먼트가 {@link
android.app.Fragment#onCreateContextMenu(ContextMenu,View,ContextMenu.ContextMenuInfo)
onCreateContextMenu()}로의 호출을 받습니다. 사용자가 항목을 하나 선택하면, 해당 프래그먼트는 {@link
android.app.Fragment#onContextItemSelected(MenuItem) onContextItemSelected()}로의 호출을 받습니다.</p>
<p class="note"><strong>참고:</strong> 프래그먼트는 추가한 각 메뉴 항목에 대해 '항목 선택됨' 콜백을
하나씩 받게 되지만, 사용자가 메뉴 항목을 선택할 때 그에 상응하는 콜백을 가장 처음 받는 것은
액티비티입니다. 액티비티가 구현한 '항목 선택됨' 콜백이 선택된 항목을 다루지 않는 경우,
해당 이벤트는 프래그먼트의 콜백으로 전달됩니다. 이것은
옵션 메뉴와 컨텍스트 메뉴에 모두 참입니다.</p>
<p>메뉴에 대한 더 자세한 정보는 <a href="{@docRoot}guide/topics/ui/menus.html">메뉴</a> 및 <a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a> 개발자 가이드를 참조하십시오.</p>
<h2 id="Lifecycle">프래그먼트 수명 주기 처리</h2>
<div class="figure" style="width:350px">
<img src="{@docRoot}images/activity_fragment_lifecycle.png" alt="" />
<p class="img-caption"><strong>그림 3.</strong> 액티비티 수명 주기가 프래그먼트 수명 주기에 미치는
영향입니다.</p>
</div>
<p>프래그먼트의 수명 주기를 관리하는 것은 액티비티의 수명 주기를 관리하는 것과 매우 비슷합니다. 액티비티와 마찬가지로
프래그먼트는 세 가지 상태로 존재할 수 있습니다.</p>
<dl>
<dt><i>재개됨</i></dt>
<dd>프래그먼트가 실행 중인 액티비티에 표시됩니다.</dd>
<dt><i>일시정지됨</i></dt>
<dd>또 다른 액티비티가 전경에 나와 있고 사용자가 이에 초점을 맞추고 있지만,
이 프래그먼트가 있는 액티비티도 여전히 표시되어 있습니다(전경의 액티비티가 부분적으로 투명하거나
전체 화면을 뒤덮지 않습니다).</dd>
<dt><i>정지됨</i></dt>
<dd>프래그먼트가 표시되지 않습니다. 호스트 액티비티가 정지되었거나
프래그먼트가 액티비티에서 제거되었지만 백 스택에 추가되었습니다. 정지된 프래그먼트도
여전히 표시는 됩니다(모든 상태 및 구성원 정보를 시스템이 보존합니다). 하지만, 사용자에게는
더 이상 표시되지 않으며 액티비티를 종료하면 이것도 종료됩니다.</dd>
</dl>
<p>이번에도 액티비티와 마찬가지로, 프래그먼트의 상태를 보존하려면 {@link
android.os.Bundle}을 사용합니다. 이는 혹시나 액티비티의 프로세스가 종료되고 액티비티를
다시 만들 때 해당 프래그먼트의 상태를 복구해야 할 필요가 있을 때를 대비하는 것입니다. 상태를 저장하려면 프래그먼트의 {@link
android.app.Fragment#onSaveInstanceState onSaveInstanceState()} 콜백 중에 저장할 수 있고, 복구는
{@link android.app.Fragment#onCreate onCreate()}, {@link
android.app.Fragment#onCreateView onCreateView()} 또는 {@link
android.app.Fragment#onActivityCreated onActivityCreated()} 중 한 가지가 진행되는 동안 할 수 있습니다. 상태 저장에 관한 자세한 정보는
<a href="{@docRoot}guide/components/activities.html#SavingActivityState">액티비티</a>
문서를 참조하십시오.</p>
<p>액티비티와 프래그먼트의 수명 주기에서 가장 중대한 차이점은
해당되는 스택에 저장되는 방법입니다. 액티비티는 중단되었을 시스템이 관리하는
액티비티 스택 안에 배치되는 것이 기본입니다(따라서 사용자가 <em>뒤로</em> 버튼을 사용하여 다시 액티비티로
뒤로 탐색할 있습니다. 내용은 <a href="{@docRoot}guide/components/tasks-and-back-stack.html">작업 스택</a>에서 설명하였습니다).
하지만, 프래그먼트가 호스트 액티비티가 관리하는 스택 안에 배치되는 것은 해당 인스턴스를 저장하라고 명시적으로 요청하는 경우뿐입니다.
이때 프래그먼트를 제거하는 트랜잭션 {@link
android.app.FragmentTransaction#addToBackStack(String) addToBackStack()}을
호출합니다.</p>
<p>이것만 제외하면, 프래그먼트 수명 주기를 관리하는 것은 액티비티의 수명 주기를 관리하는 것과
아주 비슷합니다. 따라서, <a href="{@docRoot}guide/components/activities.html#Lifecycle">액티비티
수명 주기 관리</a>에 쓰이는 실례가 프래그먼트에도 똑같이 적용되는 것입니다. 하지만 가지 이해해두어야 하는 것이 있습니다. 즉,
액티비티의 수명이 프래그먼트의 수명에 어떤 영향을 미치는지를 알아두어야 합니다.</p>
<p class="caution"><strong>주의:</strong> {@link android.app.Fragment} 내에서 {@link android.content.Context}
객체가 필요한 경우, {@link android.app.Fragment#getActivity()}를 호출하면 됩니다.
그러나 {@link android.app.Fragment#getActivity()}를 호출하는 것은 프래그먼트가 액티비티에
첨부되어 있는 경우뿐이니 유의하십시오. 프래그먼트가 아직 첨부되지 않았거나 수명 주기가 끝날 무렵 분리된 경우,
{@link android.app.Fragment#getActivity()}가 null을 반환합니다.</p>
<h3 id="CoordinatingWithActivity">액티비티 수명 주기와 조화</h3>
<p>프래그먼트가 있는 액티비티의 수명 주기는 해당 프래그먼트의 수명 주기에 직접적인
영향을 미칩니다. 따라서 액티비티에 대한 수명 주기 콜백이 프래그먼트에 대한 비슷한 콜백을
유발합니다. 예를 들어 액티비티가 {@link android.app.Activity#onPause}를 받으면,
해당 액티비티 내의 프래그먼트가 {@link android.app.Fragment#onPause}를 받습니다.</p>
<p>하지만 프래그먼트에는 가지 수명 주기 콜백이 있습니다. 이것은 액티비티와의
고유한 상호 작용을 다루어 프래그먼트의 UI 구축하고 소멸시키는 것과 같은
작업을 수행합니다. 이러한 추가적인 콜백 메서드를 예로 들면 다음과 같습니다.</p>
<dl>
<dt>{@link android.app.Fragment#onAttach onAttach()}</dt>
<dd>프래그먼트가 액티비티와 연관되어 있었던 경우 호출됩니다(여기에서 {@link
android.app.Activity}가 전달됩니다).</dd>
<dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt>
<dd>프래그먼트와 연관된 보기 계층을 생성하기 위해 호출됩니다.</dd>
<dt>{@link android.app.Fragment#onActivityCreated onActivityCreated()}</dt>
<dd>액티비티의 {@link android.app.Activity#onCreate
onCreate()} 메서드가 반환되면 호출됩니다.</dd>
<dt>{@link android.app.Fragment#onDestroyView onDestroyView()}</dt>
<dd>프래그먼트와 연관된 보기 계층이 제거되는 중일 호출됩니다.</dd>
<dt>{@link android.app.Fragment#onDetach onDetach()}</dt>
<dd>프래그먼트가 액티비티와 연결이 끊어지는 중일 호출됩니다.</dd>
</dl>
<p>호스트 액티비티의 영향을 받을 프래그먼트 수명 주기의 흐름은 그림 3에서
확인하십시오. 그림을 보면 액티비티의 연속된 상태가 프래그먼트가 어느
콜백 메서드를 받게 되는지 결정 짓는다는 것을 있습니다. 예를 들어 액티비티가 자신의 {@link
android.app.Activity#onCreate onCreate()} 콜백을 받은 경우, 해당 액티비티 안에 있는 프래그먼트는
{@link android.app.Fragment#onActivityCreated onActivityCreated()} 콜백을 받을 뿐입니다.</p>
<p>액티비티가 재개된 상태에 도달하면 자유자재로 프래그먼트를 액티비티에 추가하거나 액티비티에서
제거해도 됩니다. 따라서, 액티비티가 재개된 상태에 있는 동안에만 프래그먼트의 수명 주기를
독립적으로 변경할 있는 것입니다.</p>
<p>그러나 액티비티가 재개된 상태를 떠나면 액티비티는 다시 프래그먼트를 수명 주기 안으로
밀어넣습니다.</p>
<h2 id="Example">예</h2>
<p> 문서에서 논의한 모든 것을 번에 모아 보기 위해, 다음은 개의 프래그먼트를 사용하여
창이 개인 레이아웃을 생성하는 액티비티를 예시로 나타낸 것입니다. 아래의 액티비티에 포함된
프래그먼트는 셰익스피어 희곡 제목 목록을 표시하고, 다른 하나는 목록에서 선택했을
해당 희곡의 요약을 표시합니다. 또한 화면 구성을 근거로 프래그먼트를 여러 가지로 구성하여 제공하는 방법도
보여줍니다.</p>
<p class="note"><strong>참고:</strong> 액티비티에 대한 완전한 소스 코드는
<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.html">{@code
FragmentLayout.java}</a>에서 이용하실 수 있습니다.</p>
<p>주요 액티비티는 {@link
android.app.Activity#onCreate onCreate()} 중에 일반적인 방식으로 레이아웃을 적용합니다.</p>
{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java main}
<p>적용된 레이아웃은 {@code fragment_layout.xml}입니다.</p>
{@sample development/samples/ApiDemos/res/layout-land/fragment_layout.xml layout}
<p>시스템은 레이아웃을 사용하여 액티비티가 레이아웃을 로딩하자마자 {@code TitlesFragment}를 초기화합니다(이것이 희곡 제목을
목록으로 나열합니다). 반면 {@link android.widget.FrameLayout}
(희곡 요약을 표시하는 프래그먼트가 배치될 곳)은 화면 오른쪽에 있는
공간을 차지하기는 하지만 처음에는 상태로 유지됩니다. 아래에서 있듯이, 사용자가 해당 목록에서
항목을 하나 선택해야만 프래그먼트가 {@link android.widget.FrameLayout} 안에 배치됩니다.</p>
<p>그러나 희곡 목록과 요약을 나란히 표시할 만큼 너비가 넓지 않은
화면 구성도 있습니다. 따라서 위의 레이아웃은 가로 방향 화면 구성에만 사용되며,
이를 {@code res/layout-land/fragment_layout.xml}에 저장하여 씁니다.</p>
<p>그러므로 화면이 세로 방향으로 구성된 경우, 시스템은 다음 레이아웃을 적용합니다. 이것은
{@code res/layout/fragment_layout.xml}에 저장되어 있습니다.</p>
{@sample development/samples/ApiDemos/res/layout/fragment_layout.xml layout}
<p> 레이아웃에는 {@code TitlesFragment}만 포함되어 있습니다. 이는 다시 말해 기기가 세로 방향인 경우에는
희곡 제목 목록만 표시된다는 뜻입니다. 따라서 사용자가 구성에서 목록 항목을 하나 클릭하면,
애플리케이션이 번째 프래그먼트를 로딩하는 대신 액티비티를 시작하여 요약을
표시하게 됩니다.</p>
<p>다음으로, 프래그먼트 클래스에서 이것을 달성하는 방법을 보시겠습니다. 번째가 {@code
TitlesFragment}로, 셰익스피어 희곡 제목 목록을 표시하는 것입니다. 프래그먼트는 {@link
android.app.ListFragment}를 확장하며 목록 보기 작업의 대부분을 처리하기 위해 여기에 의존합니다.</p>
<p> 코드를 살펴보면서 사용자가 목록 항목을 클릭하면 일어날 있는 가지 동작이
있다는 점을 눈여겨 보십시오. 레이아웃 어느 것이 활성화 상태인지에 따라
같은 액티비티 내에서 세부 사항을 표시하기 위해 프래그먼트를 생성하거나 표시할 수도 있고(프래그먼트를 {@link
android.widget.FrameLayout}에 추가함으로써), 액티비티를 시작할 수도 있습니다(프래그먼트를 표시할 있는 곳).</p>
{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java titles}
<p> 번째 프래그먼트인 {@code DetailsFragment}는 {@code TitlesFragment}에서 가져온 목록에서 선택한 항목에 대한 희곡 요약을
표시하는 것입니다.</p>
{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java details}
<p>{@code TitlesFragment} 클래스에서 다룬 것을 되살려 보면, 사용자가 목록 항목을 클릭하고
현재 레이아웃이 {@code R.id.details} 보기를 포함하지 <em>않는</em> 경우(이 보기가
{@code DetailsFragment}가 속하는 곳임), 애플리케이션은 항목의 내용을 표시하기 위해 {@code DetailsActivity}
액티비티를 시작하게 됩니다.</p>
<p>다음은 화면이 세로 방향으로 구성되어 있을 선택한 희곡의 요약을 표시하기 위해 단순히 {@code DetailsFragment}를
포함할 뿐인 {@code DetailsActivity}입니다.</p>
{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
details_activity}
<p> 액티비티는 구성이 가로 방향인 경우 알아서 종료한다는 점을 눈여겨 보십시오. 따라서
주요 액티비티가 작업을 인계 받아 {@code DetailsFragment}를 {@code TitlesFragment}와 함께 표시할 있는 것입니다.
이것은 사용자가 세로 방향 구성에서 {@code DetailsActivity}를 시작했지만
그런 다음 가로 방향으로 돌리는 경우(현재 액티비티를 다시 시작함) 일어날 있습니다.</p>
<p>프래그먼트 사용에 대한 많은 샘플(및 예시에 대한 완전한 소스 파일)을 보시려면
<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment">
ApiDemos</a>에서 이용할 수 있는 API Demos 샘플 앱을 참조하십시오(<a href="{@docRoot}resources/samples/get.html">샘플 SDK 구성 요소</a>에서 다운로드할 수 있습니다).</p>