• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Phân đoạn
2parent.title=Hoạt động
3parent.link=activities.html
4@jd:body
5
6<div id="qv-wrapper">
7<div id="qv">
8  <h2>Trong tài liệu này</h2>
9  <ol>
10    <li><a href="#Design">Triết lý Thiết kế</a></li>
11    <li><a href="#Creating">Tạo một Phân đoạn</a>
12      <ol>
13        <li><a href="#UI">Thêm một giao diện người dùng</a></li>
14        <li><a href="#Adding">Thêm một phân đoạn vào một hoạt động</a></li>
15      </ol>
16    </li>
17    <li><a href="#Managing">Quản lý Phân đoạn</a></li>
18    <li><a href="#Transactions">Thực hiện Giao tác Phân đoạn</a></li>
19    <li><a href="#CommunicatingWithActivity">Giao tiếp với Hoạt động</a>
20      <ol>
21        <li><a href="#EventCallbacks">Tạo gọi lại sự kiện cho hoạt động</a></li>
22        <li><a href="#ActionBar">Thêm mục vào Thanh Hành động</a></li>
23      </ol>
24    </li>
25    <li><a href="#Lifecycle">Xử lý Vòng đời của Phân đoạn</a>
26      <ol>
27        <li><a href="#CoordinatingWithActivity">Phối hợp với vòng đời của hoạt động</a></li>
28      </ol>
29    </li>
30    <li><a href="#Example">Ví dụ</a></li>
31  </ol>
32
33  <h2>Lớp khóa</h2>
34  <ol>
35    <li>{@link android.app.Fragment}</li>
36    <li>{@link android.app.FragmentManager}</li>
37    <li>{@link android.app.FragmentTransaction}</li>
38  </ol>
39
40  <h2>Xem thêm</h2>
41  <ol>
42    <li><a href="{@docRoot}training/basics/fragments/index.html">Xây dựng một UI Động bằng các Phân đoạn</a></li>
43    <li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">Hỗ trợ Máy tính bảng
44và Thiết bị cầm tay</a></li>
45  </ol>
46</div>
47</div>
48
49<p>{@link android.app.Fragment} biểu diễn một hành vi hay một phần giao diện người dùng trong một
50{@link android.app.Activity}. Bạn có thể kết hợp nhiều phân đoạn trong một hoạt động duy nhất để xây dựng một
51UI nhiều bảng và sử dụng lại phân đoạn trong nhiều hoạt động. Bạn có thể coi phân đoạn như là một
52phần mô-đun của một hoạt động, có vòng đời của chính nó, nhận các sự kiện đầu vào của chính nó, và
53bạn có thể thêm hoặc gỡ bỏ trong khi hoạt động đang chạy (kiểu như một "hoạt động con" mà
54bạn có thể sử dụng lại trong các hoạt động khác nhau).</p>
55
56<p>Phân đoạn phải luôn được nhúng trong một hoạt động và vòng đời của phân đoạn bị ảnh hưởng trực tiếp bởi
57vòng đời của hoạt động chủ. Ví dụ, khi hoạt động bị tạm dừng, tất cả
58phân đoạn trong nó cũng vậy, và khi hoạt động bị hủy, tất cả phân đoạn cũng vậy. Tuy nhiên, trong khi một
59hoạt động đang chạy (nó ở trong trạng thái vòng đời <em>được tiếp tục</em><a href="{@docRoot}guide/components/activities.html#Lifecycle"></a>), bạn có thể
60thao tác từng phân đoạn độc lập, chẳng hạn như thêm hay xóa chúng. Khi bạn thực hiện một
61giao tác phân đoạn, bạn cũng có thể thêm nó vào một ngăn xếp được quản lý bởi
62hoạt động đó&mdash;từng mục nhập vào ngăn xếp trong hoạt động là một bản ghi giao tác phân đoạn
63đã xảy ra. Ngăn xếp cho phép người dùng đảo ngược một giao tác phân đoạn (điều hướng ngược lại),
64bằng cách nhấn nút <em>Quay lại</em>.</p>
65
66<p>Khi bạn thêm một phân đoạn như một phần trong bố trí hoạt động của mình, nó sẽ ở trong một {@link
67android.view.ViewGroup} bên trong phân cấp dạng xem của hoạt động đó và phân đoạn này sẽ định nghĩa bố trí
68dạng xem của chính nó.
69Bạn có thể chèn một phân đoạn vào bố trí hoạt động của mình bằng cách khai báo phân đoạn trong tệp
70bố trí của hoạt động, dưới dạng một phần tử {@code &lt;fragment&gt;}, hoặc từ mã ứng dụng của bạn bằng cách thêm nó vào một
71{@link android.view.ViewGroup} hiện hữu. Tuy nhiên, không bắt buộc phải có một phân đoạn là một bộ phận của bố trí hoạt động
72; bạn cũng có thể sử dụng một phân đoạn mà không cần UI của chính nó như một trình thực hiện vô hình cho hoạt động
73.</p>
74
75<p>Tài liệu này mô tả cách xây dựng ứng dụng của bạn để sử dụng phân đoạn, bao gồm
76cách các phân đoạn có thể duy trì trạng thái của chúng khi được thêm vào ngăn xếp của hoạt động, chia sẻ
77các sự kiện với hoạt động và các phân đoạn khác trong hoạt động, đóng góp vào thanh hành động của hoạt động
78và nhiều thông tin khác.</p>
79
80
81<h2 id="Design">Triết lý Thiết kế</h2>
82
83<p>Android giới thiệu phân đoạn trong phiên bản Android 3.0 (API mức 11), chủ yếu nhằm hỗ trợ
84các thiết kế UI động và linh hoạt hơn trên màn hình lớn, chẳng hạn như máy tính bảng. Vì
85màn hình của máy tính bảng lớn hơn nhiều màn hình của thiết bị cầm tay, có nhiều khoảng trống hơn để kết hợp và
86trao đổi các thành phần UI. Phân đoạn cho phép những thiết kế như vậy mà không cần bạn phải quản lý những thay đổi
87phức tạp về phân cấp dạng xem. Bằng cách chia bố trí của một hoạt động thành các phân đoạn, bạn có thể
88sửa đổi diện mạo của hoạt động vào thời gian chạy và giữ những thay đổi đó trong một ngăn xếp
89được quản lý bởi hoạt động.</p>
90
91<p>Ví dụ, một ứng dụng tin tức có thể sử dụng một phân đoạn để hiển thị một danh sách bài viết ở
92bên trái và một phân đoạn khác để hiển thị một bài viết ở bên phải&mdash;cả hai phân đoạn đều xuất hiện trong một
93hoạt động, bên cạnh nhau, và từng phân đoạn có tập phương pháp gọi lại vòng đời riêng và xử lý
94các sự kiện nhập liệu người dùng riêng của mình. Vì thế, thay vì sử dụng một hoạt động để chọn một bài viết và một
95hoạt động khác để đọc bài viết, người dùng có thể chọn một bài viết và đọc nó trong cùng
96hoạt động, như được minh họa trong bố trí máy tính bảng trong hình 1.</p>
97
98<p>Bạn nên thiết kế từng phân đoạn như một thành phần hoạt động dạng mô-đun và có thể sử dụng lại. Đó là bởi
99mỗi phân đoạn sẽ định nghĩa bố trí và hành vi của chính nó với các phương pháp gọi lại vòng đời của chính nó, bạn có thể
100bao gồm một phân đoạn trong nhiều hoạt động, vì thế bạn nên thiết kế để tái sử dụng và tránh trực tiếp
101thao tác một phân đoạn từ một phân đoạn khác. Điều này đặc biệt quan trọng vì một phân đoạn
102mô-đun cho phép bạn thay đổi kết hợp phân đoạn của mình cho các kích cỡ màn hình khác nhau. Khi thiết kế
103ứng dụng của bạn để hỗ trợ cả máy tính bảng và thiết bị cầm tay, bạn có thể sử dụng lại phân đoạn của mình trong các cấu hình
104bố trí khác nhau nhằm tối ưu hóa trải nghiệm người dùng dựa trên không gian màn hình có sẵn. Ví
105dụ, trên một thiết bị cầm tay, có thể cần phải tách riêng các phân đoạn để cung cấp một UI đơn bảng khi mà
106không thể làm vừa khít nhiều hơn một phân đoạn trong cùng hoạt động.</p>
107
108<img src="{@docRoot}images/fundamentals/fragments.png" alt="" />
109<p class="img-caption"><strong>Hình 1.</strong> Ví dụ về cách hai mô-đun UI được định nghĩa
110bởi các phân đoạn có thể được kết hợp thành một hoạt động đối với thiết kế máy tính bảng, nhưng được tách riêng đối với
111thiết kế thiết bị cầm tay.</p>
112
113<p>Ví dụ&mdash;để tiếp tục với ví dụ về ứng dụng tin tức&mdash;ứng dụng có thể nhúng
114hai phân đoạn trong <em>Hoạt động A</em>, khi đang chạy trên một thiết bị có kích cỡ máy tính bảng. Tuy nhiên, trên một
115màn hình kích cỡ thiết bị cầm tay, không có đủ khoảng trống cho cả hai phân đoạn, vì thế <em>Hoạt động A</em> chỉ
116bao gồm phân đoạn cho danh sách bài viết, và khi người dùng chọn một bài viết, nó sẽ khởi động
117<em>Hoạt động B</em>, hoạt động này chứa phân đoạn thứ hai là đọc bài viết. Vì thế, ứng dụng
118hỗ trợ cả máy tính bảng và thiết bị cầm tay bằng cách sử dụng lại các phân đoạn theo các cách kết hợp khác nhau như được minh họa trong
119hình 1.</p>
120
121<p>Để biết thêm thông tin về việc thiết kế ứng dụng của bạn bằng các cách kết hợp phân đoạn khác nhau cho
122cấu hình màn hình khác nhau, hãy xem hướng dẫn <a href="{@docRoot}guide/practices/tablets-and-handsets.html">Hỗ trợ Máy tính bảng và Thiết bị cầm tay</a>.</p>
123
124
125
126<h2 id="Creating">Tạo một Phân đoạn</h2>
127
128<div class="figure" style="width:327px">
129<img src="{@docRoot}images/fragment_lifecycle.png" alt="" />
130<p class="img-caption"><strong>Hình 2.</strong> Vòng đời của một phân đoạn (trong khi hoạt động
131của nó đang chạy).</p>
132</div>
133
134<p>Để tạo một phân đoạn, bạn phải tạo một lớp con của {@link android.app.Fragment} (hoặc
135một lớp con hiện tại của nó). Lớp {@link android.app.Fragment} có mã trông rất giống
136một {@link android.app.Activity}. Nó chứa các phương pháp gọi lại tương tự như hoạt động, chẳng
137hạn như {@link android.app.Fragment#onCreate onCreate()}, {@link android.app.Fragment#onStart onStart()},
138{@link android.app.Fragment#onPause onPause()}, và {@link android.app.Fragment#onStop onStop()}. Trên
139thực tế, nếu bạn đang chuyển đổi một ứng dụng Android hiện tại để sử dụng các phân đoạn, bạn có thể chỉ cần di chuyển
140mã khỏi các phương pháp gọi lại của hoạt động của bạn vào các phương pháp gọi lại tương ứng của phân đoạn
141của bạn.</p>
142
143<p>Thường thì ít nhất bạn nên triển khai các phương pháp vòng đời sau:</p>
144
145<dl>
146  <dt>{@link android.app.Fragment#onCreate onCreate()}</dt>
147  <dd>Hệ thống sẽ gọi phương pháp này khi tạo phân đoạn. Trong triển khai của mình, bạn nên
148khởi tạo các thành phần thiết yếu của phân đoạn mà bạn muốn giữ lại khi phân đoạn
149bị tạm dừng hoặc dừng hẳn, sau đó tiếp tục.</dd>
150  <dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt>
151  <dd>Hệ thống sẽ gọi phương pháp này khi đến lúc phân đoạn vẽ giao diện người dùng của nó
152lần đầu tiên. Để vẽ một UI cho phân đoạn của mình, bạn phải trả về một {@link android.view.View} từ phương pháp
153này, đây là gốc của bố trí phân đoạn của bạn. Bạn có thể trả về giá trị rỗng nếu phân đoạn không
154cung cấp UI.</dd>
155  <dt>{@link android.app.Activity#onPause onPause()}</dt>
156  <dd>Hệ thống gọi phương pháp này là dấu hiệu đầu tiên về việc người dùng đang rời khỏi
157phân đoạn (mặc dù không phải lúc nào cũng có nghĩa rằng phân đoạn đang bị hủy). Trường hợp này thường là khi bạn
158định thực hiện bất kỳ thay đổi nào vẫn cần có hiệu lực ngoài phiên của người dùng hiện thời (vì
159người dùng có thể không quay lại).</dd>
160</dl>
161
162<p>Phần lớn ứng dụng nên triển khai ít nhất ba phương pháp sau đối với mọi phân đoạn, nhưng có một vài
163phương pháp gọi lại khác mà bạn cũng nên sử dụng để xử lý các giai đoạn khác nhau trong
164vòng đời của phân đoạn. Tất cả phương pháp gọi lại vòng đời được đề cập chi tiết hơn trong phần
165về <a href="#Lifecycle">Xử lý Vòng đời của Phân đoạn</a>.</p>
166
167
168<p>Cũng có một vài lớp con mà bạn có thể muốn mở rộng thay vì lớp cơ bản {@link
169android.app.Fragment}:</p>
170
171<dl>
172  <dt>{@link android.app.DialogFragment}</dt>
173  <dd>Hiển thị một hộp thoại trôi nổi. Sử dụng lớp này để tạo một hộp thoại là một phương án hay cho việc sử dụng các phương pháp trình trợ giúp
174hộp thoại trong lớp {@link android.app.Activity}, vì bạn có thể
175kết hợp một hộp thoại phân đoạn vào ngăn xếp của các phân đoạn được quản lý bởi hoạt động,
176cho phép người dùng trả về một phân đoạn bị bỏ.</dd>
177
178  <dt>{@link android.app.ListFragment}</dt>
179  <dd>Hiển thị một danh sách các mục được quản lý bởi một trình điều hợp (chẳng hạn như một {@link
180android.widget.SimpleCursorAdapter}), tương tự như {@link android.app.ListActivity}. Nó cung cấp
181một vài phương pháp để quản lý một dạng xem danh sách, chẳng hạn như phương pháp gọi lại {@link
182android.app.ListFragment#onListItemClick(ListView,View,int,long) onListItemClick()} để
183xử lý các sự kiện nhấp.</dd>
184
185  <dt>{@link android.preference.PreferenceFragment}</dt>
186  <dd>Hiển thị một phân cấp các đối tượng {@link android.preference.Preference} dưới dạng một danh sách, tương tự như
187{@link android.preference.PreferenceActivity}. Điều này hữu ích khi tạo một hoạt động "thiết đặt"
188cho ứng dụng của bạn.</dd>
189</dl>
190
191
192<h3 id="UI">Thêm một giao diện người dùng</h3>
193
194<p>Phân đoạn thường được sử dụng như một phần giao diện người dùng của hoạt động và đóng góp bố trí của
195chính nó cho hoạt động.</p>
196
197<p>Để cung cấp một bố trí cho một phân đoạn, bạn phải triển khai phương pháp gọi lại {@link
198android.app.Fragment#onCreateView onCreateView()}, phương pháp này được hệ thống Android gọi
199khi đến lúc phân đoạn vẽ bố trí của nó. Việc bạn triển khai phương pháp này phải trả về một
200{@link android.view.View} là phần gốc cho bố trí phân đoạn của bạn.</p>
201
202<p class="note"><strong>Lưu ý:</strong> Nếu phân đoạn của bạn là một lớp con của {@link
203android.app.ListFragment}, triển khai mặc định sẽ trả về một {@link android.widget.ListView} từ
204{@link android.app.Fragment#onCreateView onCreateView()}, vì thế bạn không cần triển khai nó.</p>
205
206<p>Để trả về một bố trí từ {@link
207android.app.Fragment#onCreateView onCreateView()}, bạn có thể bung nó từ một <a href="{@docRoot}guide/topics/resources/layout-resource.html">tài nguyên bố trí</a> được định nghĩa trong XML. Để
208giúp bạn làm vậy, {@link android.app.Fragment#onCreateView onCreateView()} cung cấp một đối tượng
209{@link android.view.LayoutInflater}.</p>
210
211<p>Ví dụ, sau đây là một lớp con của {@link android.app.Fragment} với chức năng nạp một bố trí từ tệp
212{@code example_fragment.xml}:</p>
213
214<pre>
215public static class ExampleFragment extends Fragment {
216    &#64;Override
217    public View onCreateView(LayoutInflater inflater, ViewGroup container,
218                             Bundle savedInstanceState) {
219        // Inflate the layout for this fragment
220        return inflater.inflate(R.layout.example_fragment, container, false);
221    }
222}
223</pre>
224
225<div class="sidebox-wrapper">
226<div class="sidebox">
227  <h3>Tạo một bố trí</h3>
228  <p>Trong ví dụ trên, {@code R.layout.example_fragment} là một tham chiếu tới tài nguyên bố trí
229có tên {@code example_fragment.xml} được lưu trong tài nguyên ứng dụng. Để biết thông tin về cách
230tạo một bố trí trong XML, hãy xem tài liệu <a href="{@docRoot}guide/topics/ui/index.html">Giao diện Người dùng</a>
231.</p>
232</div>
233</div>
234
235<p>Tham số {@code container} được chuyển tới {@link android.app.Fragment#onCreateView
236onCreateView()} là {@link android.view.ViewGroup} mẹ (tức bố trí của hoạt động), trong đó
237bố trí phân đoạn của bạn
238sẽ được chèn vào. Tham số {@code savedInstanceState} là một {@link android.os.Bundle} có chức năng
239cung cấp dữ liệu về thực thể trước đó của phân đoạn, nếu phân đoạn đang được tiếp tục
240(việc khôi phục trạng thái được bàn kỹ hơn trong phần về <a href="#Lifecycle">Xử lý
241Vòng đời của Phân đoạn</a>).</p>
242
243<p>Phương pháp {@link android.view.LayoutInflater#inflate(int,ViewGroup,boolean) inflate()} có
244ba tham đối:</p>
245<ul>
246  <li>ID tài nguyên của bố trí mà bạn muốn bung.</li>
247  <li>{@link android.view.ViewGroup} là mẹ của bố trí được bung. Việc chuyển {@code
248container} có vai trò quan trọng để hệ thống áp dụng các tham số bố trí cho dạng xem gốc của bố trí
249được bung, được quy định bởi dạng xem mẹ là nơi mà nó diễn ra trong đó.</li>
250  <li>Một boolean cho biết bố trí được bung có nên được gắn với {@link
251android.view.ViewGroup} (tham số thứ hai) trong khi bung hay không. (Trong trường hợp này, điều này là
252sai vì hệ thống đã đang chèn bố trí được bung vào {@code
253container}&mdash;việc chuyển đúng sẽ tạo ra một nhóm dạng xem thừa trong bố trí cuối cùng.)</li>
254</ul>
255
256<p>Giờ bạn đã thấy cách tạo một phân đoạn nhằm cung cấp một bố trí. Tiếp theo, bạn cần thêm
257phân đoạn vào hoạt động của mình.</p>
258
259
260
261<h3 id="Adding">Thêm một phân đoạn vào một hoạt động</h3>
262
263<p>Thường thì một phân đoạn đóng góp một phần UI vào hoạt động chủ, nó được nhúng như một phần
264trong phân cấp dạng xem tổng thể của hoạt động. Có hai cách mà bạn có thể thêm một phân đoạn vào bố trí
265của hoạt động:</p>
266
267<ul>
268  <li><b>Khai báo phân đoạn bên trong tệp bố trí của hoạt động.</b>
269<p>Trong trường hợp này, bạn có thể
270chỉ định các tính chất bố trí cho phân đoạn như thể nó là một dạng xem. Ví dụ, sau đây là tệp bố trí
271cho một hoạt động có hai phân đoạn:</p>
272<pre>
273&lt;?xml version="1.0" encoding="utf-8"?&gt;
274&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
275    android:orientation="horizontal"
276    android:layout_width="match_parent"
277    android:layout_height="match_parent"&gt;
278    &lt;fragment android:name="com.example.news.ArticleListFragment"
279            android:id="@+id/list"
280            android:layout_weight="1"
281            android:layout_width="0dp"
282            android:layout_height="match_parent" /&gt;
283    &lt;fragment android:name="com.example.news.ArticleReaderFragment"
284            android:id="@+id/viewer"
285            android:layout_weight="2"
286            android:layout_width="0dp"
287            android:layout_height="match_parent" /&gt;
288&lt;/LinearLayout&gt;
289</pre>
290  <p>Thuộc tính {@code android:name} trong {@code &lt;fragment&gt;} sẽ chỉ định lớp {@link
291android.app.Fragment} để khởi tạo trong bố trí.</p>
292
293<p>Khi hệ thống tạo bố trí hoạt động này, nó sẽ khởi tạo từng phân đoạn được chỉ định trong bố trí
294và gọi ra phương pháp {@link android.app.Fragment#onCreateView onCreateView()} cho từng phân đoạn,
295để truy xuất bố trí của từng phân đoạn. Hệ thống sẽ chèn {@link android.view.View} được trả về bởi phân đoạn
296trực tiếp thế chỗ phần tử {@code &lt;fragment&gt;}.</p>
297
298<div class="note">
299  <p><strong>Lưu ý:</strong> Mỗi phân đoạn yêu cầu một mã định danh duy nhất
300mà hệ thống có thể sử dụng để khôi phục phân đoạn nếu hoạt động bị khởi động lại (và bạn có thể sử dụng để
301nắm bắt phân đoạn sẽ thực hiện giao tác, chẳng hạn như gỡ bỏ nó). Có ba cách để cung cấp ID cho một
302phân đoạn:</p>
303  <ul>
304    <li>Cung cấp thuộc tính {@code android:id} với một ID duy nhất.</li>
305    <li>Cung cấp thuộc tính {@code android:tag} với một xâu duy nhất.</li>
306    <li>Nếu bạn không cung cấp được thuộc tính nào, hệ thống sẽ sử dụng ID của dạng xem
307của bộ chứa.</li>
308  </ul>
309</div>
310  </li>
311
312  <li><b>Hoặc, bằng cách lập trình, thêm phân đoạn vào một {@link android.view.ViewGroup} hiện hữu.</b>
313<p>Vào bất cứ lúc nào trong khi hoạt động của bạn đang chạy, bạn có thể thêm phân đoạn vào bố trí hoạt động của mình. Bạn
314chỉ cần chỉ định một {@link
315android.view.ViewGroup} là nơi mà bạn sẽ đặt phân đoạn vào.</p>
316  <p>Để thực hiện giao tác phân đoạn trong hoạt động của mình (chẳng hạn như thêm, gỡ bỏ, hay thay thế một
317phân đoạn), bạn phải sử dụng các API từ {@link android.app.FragmentTransaction}. Bạn có thể nhận một thực thể
318của {@link android.app.FragmentTransaction} từ {@link android.app.Activity} của mình như sau:</p>
319
320<pre>
321FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()}
322FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()};
323</pre>
324
325<p>Sau đó, bạn có thể thêm một phân đoạn bằng cách sử dụng phương pháp {@link
326android.app.FragmentTransaction#add(int,Fragment) add()}, chỉ định phân đoạn sẽ thêm và
327dạng xem mà bạn sẽ chèn nó vào. Ví dụ:</p>
328
329<pre>
330ExampleFragment fragment = new ExampleFragment();
331fragmentTransaction.add(R.id.fragment_container, fragment);
332fragmentTransaction.commit();
333</pre>
334
335  <p>Tham đối đầu tiên được chuyển cho {@link android.app.FragmentTransaction#add(int,Fragment) add()}
336là {@link android.view.ViewGroup}, là nơi mà phân đoạn sẽ được đặt vào, được chỉ định bởi
337ID tài nguyên, và tham đối thứ hai là phân đoạn cần thêm.</p>
338  <p>Sau khi bạn đã thực hiện các thay đổi của mình bằng
339{@link android.app.FragmentTransaction}, bạn phải
340gọi {@link android.app.FragmentTransaction#commit} để các thay đổi có hiệu lực.</p>
341  </li>
342</ul>
343
344
345<h4 id="AddingWithoutUI">Thêm một phân đoạn không có UI</h4>
346
347<p>Các ví dụ nêu trên cho biết cách thêm một phân đoạn vào hoạt động của bạn để cung cấp một UI. Tuy nhiên,
348bạn cũng có thể sử dụng một phân đoạn để cung cấp một hành vi chạy ngầm cho hoạt động mà không cần đưa
349UI bổ sung.</p>
350
351<p>Để thêm một phân đoạn không có UI, hãy thêm phân đoạn từ hoạt động đang bằng cách sử dụng {@link
352android.app.FragmentTransaction#add(Fragment,String)} (cung cấp một "tag" xâu duy nhất cho phân đoạn
353, thay vì một ID dạng xem). Làm vậy sẽ thêm phân đoạn, nhưng vì không liên kết với một dạng xem
354trong bố trí hoạt động, nó sẽ không nhận được lệnh gọi tới {@link
355android.app.Fragment#onCreateView onCreateView()}. Vì thế, bạn không cần triển khai phương pháp đó.</p>
356
357<p>Việc cung cấp tag xâu cho phân đoạn không chỉ áp dụng cho các phân đoạn không có UI&mdash;bạn cũng có thể
358cung cấp tag xâu cho phân đoạn có UI&mdash;nhưng nếu phân đoạn không có
359UI, khi đó, tag xâu là cách duy nhất để nhận biết nó. Nếu sau này bạn muốn nhận phân đoạn từ
360hoạt động, bạn cần sử dụng {@link android.app.FragmentManager#findFragmentByTag
361findFragmentByTag()}.</p>
362
363<p>Để biết ví dụ về hoạt động sử dụng phân đoạn như một trình thực hiện nền, không có UI, hãy xem mẫu {@code
364FragmentRetainInstance.java}, mẫu này có trong các mẫu SDK (có sẵn thông qua
365Trình quản lý SDK Android) và nằm trên hệ thống của bạn như là
366<code>&lt;sdk_root&gt;/APIDemos/app/src/main/java/com/example/android/apis/app/FragmentRetainInstance.java</code>.</p>
367
368
369
370<h2 id="Managing">Quản lý Phân đoạn</h2>
371
372<p>Để quản lý các phân đoạn trong hoạt động của mình, bạn cần sử dụng {@link android.app.FragmentManager}. Để
373có nó, hãy gọi {@link android.app.Activity#getFragmentManager()} từ hoạt động của bạn.</p>
374
375<p>Một số việc bạn có thể làm với {@link android.app.FragmentManager} bao gồm:</p>
376
377<ul>
378  <li>Nhận các phân đoạn tồn tại trong hoạt động, bằng {@link
379android.app.FragmentManager#findFragmentById findFragmentById()} (đối với các phân đoạn cung cấp UI trong
380bố trí hoạt động) hoặc {@link android.app.FragmentManager#findFragmentByTag
381findFragmentByTag()} (đối với các phân đoạn có hoặc không cung cấp UI).</li>
382  <li>Lấy phân đoạn ra khỏi ngăn xếp, bằng {@link
383android.app.FragmentManager#popBackStack()} (mô phỏng một câu lệnh <em>Quay lại</em> của người dùng).</li>
384  <li>Đăng ký một đối tượng theo dõi cho những thay đổi đối với ngăn xếp, bằng {@link
385android.app.FragmentManager#addOnBackStackChangedListener addOnBackStackChangedListener()}.</li>
386</ul>
387
388<p>Để biết thêm thông tin về những phương pháp này và phương pháp khác, hãy tham khảo tài liệu lớp {@link
389android.app.FragmentManager}.</p>
390
391<p>Như minh họa trong phần trước, bạn cũng có thể sử dụng {@link android.app.FragmentManager}
392để mở một {@link android.app.FragmentTransaction}, nó cho phép bạn thực hiện các giao tác, ví dụ như
393thêm hoặc gỡ bỏ phân đoạn.</p>
394
395
396<h2 id="Transactions">Thực hiện Giao tác Phân đoạn</h2>
397
398<p>Một tính năng tuyệt vời khi sử dụng phân đoạn trong hoạt động của bạn đó là khả năng thêm, gỡ bỏ, thay thế,
399và thực hiện các hành động khác với chúng, để hồi đáp lại tương tác của người dùng. Mỗi tập hợp thay đổi mà bạn
400thực thi cho hoạt động được gọi là một giao tác và bạn có thể thực hiện một giao tác bằng cách sử dụng các API trong {@link
401android.app.FragmentTransaction}. Bạn cũng có thể lưu từng giao tác vào một ngăn xếp được quản lý bởi
402hoạt động, cho phép người dùng điều hướng ngược lại thông qua những thay đổi phân đoạn (tương tự như điều hướng
403ngược lại thông qua hoạt động).</p>
404
405<p>Bạn có thể thu được một thực thể của {@link android.app.FragmentTransaction} từ {@link
406android.app.FragmentManager} như sau:</p>
407
408<pre>
409FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()};
410FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()};
411</pre>
412
413<p>Mỗi giao tác là một tập hợp những thay đổi mà bạn muốn thực hiện tại cùng thời điểm. Bạn có thể thiết lập
414tất cả thay đổi mà mình muốn thực hiện đối với một giao tác cho trước bằng cách sử dụng các phương pháp như {@link
415android.app.FragmentTransaction#add add()}, {@link android.app.FragmentTransaction#remove remove()},
416và {@link android.app.FragmentTransaction#replace replace()}. Sau đó, để áp dụng giao tác
417cho hoạt động, bạn phải gọi {@link android.app.FragmentTransaction#commit()}.</p>
418</dl>
419
420<p>Trước khi bạn gọi {@link
421android.app.FragmentTransaction#commit()}, tuy nhiên, bạn có thể muốn gọi {@link
422android.app.FragmentTransaction#addToBackStack addToBackStack()}, để thêm giao tác
423vào một ngăn xếp của các giao tác phân đoạn. Ngăn xếp này được quản lý bởi hoạt động và cho phép
424người dùng trở về trạng thái phân đoạn trước đó, bằng cách nhấp nút <em>Quay lại</em>.</p>
425
426<p>Ví dụ, sau đây là cách bạn có thể thay thế phân đoạn này bằng phân đoạn khác, và giữ nguyên
427trạng thái trước đó của ngăn xếp:</p>
428
429<pre>
430// Create new fragment and transaction
431Fragment newFragment = new ExampleFragment();
432FragmentTransaction transaction = getFragmentManager().beginTransaction();
433
434// Replace whatever is in the fragment_container view with this fragment,
435// and add the transaction to the back stack
436transaction.replace(R.id.fragment_container, newFragment);
437transaction.addToBackStack(null);
438
439// Commit the transaction
440transaction.commit();
441</pre>
442
443<p>Trong ví dụ này, {@code newFragment} thay thế mọi phân đoạn (nếu có) hiện đang ở trong
444bộ chứa bố trí được nhận biết bởi ID {@code R.id.fragment_container}. Bằng cách gọi {@link
445android.app.FragmentTransaction#addToBackStack addToBackStack()}, giao tác thay thế
446được lưu vào ngăn xếp, vì thế người dùng có thể đảo ngược giao tác và mang
447giao tác trước đó trở lại bằng cách nhấn nút <em>Quay lại</em>.</p>
448
449<p>Nếu bạn thêm nhiều thay đổi vào giao tác (chẳng hạn như một {@link
450android.app.FragmentTransaction#add add()} khác hoặc {@link android.app.FragmentTransaction#remove
451remove()}) và gọi {@link
452android.app.FragmentTransaction#addToBackStack addToBackStack()}, khi đó, tất cả thay đổi được áp dụng
453trước khi bạn gọi {@link android.app.FragmentTransaction#commit commit()} đều được thêm vào
454ngăn xếp như một giao tác riêng lẻ và nút <em>Quay lại</em> sẽ đảo ngược tất cả cùng nhau.</p>
455
456<p>Thứ tự mà bạn thêm thay đổi vào một {@link android.app.FragmentTransaction} không quan trọng,
457ngoại trừ:</p>
458<ul>
459  <li>Bạn phải gọi {@link android.app.FragmentTransaction#commit()} cuối cùng</li>
460  <li>Nếu bạn thêm nhiều phân đoạn vào cùng bộ chứa, khi đó thứ tự mà
461bạn thêm chúng sẽ xác định thứ tự chúng xuất hiện trong phân cấp dạng xem</li>
462</ul>
463
464<p>Nếu bạn không gọi {@link android.app.FragmentTransaction#addToBackStack(String)
465addToBackStack()} khi thực hiện một giao tác để xóa một phân đoạn, khi đó, phân đoạn đó sẽ bị
466hủy khi giao tác được thực hiện và người dùng không thể điều hướng trở lại nó. Trong khi đó, nếu bạn
467gọi {@link android.app.FragmentTransaction#addToBackStack(String) addToBackStack()} khi
468gỡ bỏ một phân đoạn, khi đó phân đoạn bị <em>dừng</em> và sẽ được khôi phục nếu người dùng điều hướng
469trở lại.</p>
470
471<p class="note"><strong>Mẹo:</strong> Với mỗi giao tác phân đoạn, bạn có thể áp dụng một hoạt ảnh
472chuyển tiếp bằng cách gọi {@link android.app.FragmentTransaction#setTransition setTransition()} trước khi
473thực thi.</p>
474
475<p>Việc gọi {@link android.app.FragmentTransaction#commit()} không thực hiện giao tác
476ngay lập tức. Thay vào đó, nó lập lịch biểu để chạy trên luồng UI của hoạt động (luồng "chính") ngay khi
477luồng có thể làm vậy. Tuy nhiên, nếu cần, bạn có thể gọi {@link
478android.app.FragmentManager#executePendingTransactions()} từ luồng UI của mình để ngay lập tức thực hiện
479các giao tác được gửi bởi {@link android.app.FragmentTransaction#commit()}. Làm vậy
480thường không cần thiết trừ khi giao tác đó là phụ thuộc cho các tác vụ ở những luồng khác.</p>
481
482<p class="caution"><strong>Chú ý:</strong> Bạn có thể thực thi một giao tác bằng cách sử dụng {@link
483android.app.FragmentTransaction#commit commit()} chỉ trước khi hoạt động <a href="{@docRoot}guide/components/activities.html#SavingActivityState">lưu
484trạng thái</a> của nó (khi người dùng rời khỏi hoạt động). Nếu bạn định thực thi sau thời điểm đó sẽ phát sinh một lỗi
485ngoại lệ. Nguyên nhân là vì trạng thái sau khi thực thi có thể bị mất nếu hoạt động
486cần được khôi phục. Đối với những trường hợp mà bạn có thể mất thực thi, hãy sử dụng {@link
487android.app.FragmentTransaction#commitAllowingStateLoss()}.</p>
488
489
490
491
492<h2 id="CommunicatingWithActivity">Giao tiếp với Hoạt động</h2>
493
494<p>Mặc dù {@link android.app.Fragment} được triển khai như một đối tượng độc lập với
495{@link android.app.Activity} và có thể được sử dụng bên trong nhiều hoạt động, một thực thể đã cho của
496phân đoạn sẽ được gắn kết trực tiếp với hoạt động chứa nó.</p>
497
498<p>Cụ thể, phân đoạn có thể truy cập thực thể {@link android.app.Activity} bằng {@link
499android.app.Fragment#getActivity()} và dễ dàng thực hiện các tác vụ như tìm một dạng xem trong bố trí
500hoạt động:</p>
501
502<pre>
503View listView = {@link android.app.Fragment#getActivity()}.{@link android.app.Activity#findViewById findViewById}(R.id.list);
504</pre>
505
506<p>Tương tự, hoạt động của bạn có thể gọi ra các phương pháp trong phân đoạn bằng cách thu được một tham chiếu tới
507{@link android.app.Fragment} từ {@link android.app.FragmentManager}, bằng cách sử dụng {@link
508android.app.FragmentManager#findFragmentById findFragmentById()} hoặc {@link
509android.app.FragmentManager#findFragmentByTag findFragmentByTag()}. Ví dụ:</p>
510
511<pre>
512ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
513</pre>
514
515
516<h3 id="EventCallbacks">Tạo gọi lại sự kiện cho hoạt động</h3>
517
518<p>Trong một số trường hợp, bạn có thể cần một phân đoạn để chia sẻ sự kiện với hoạt động. Một cách hay để làm điều này
519đó là định nghĩa một giao diện gọi lại bên trong phân đoạn và yêu cầu hoạt động chủ triển khai
520nó. Khi hoạt động nhận được một lệnh gọi lại thông qua giao diện, nó có thể chia sẻ thông tin với
521các phân đoạn khác trong bố trí nếu cần.</p>
522
523<p>Ví dụ, nếu một ứng dụng tin tức có hai phân đoạn trong một hoạt động&mdash;một để hiển thị danh sách
524bài viết (phân đoạn A) và một để hiển thị một bài viết (phân đoạn B)&mdash;khi đó, phân đoạn A phải thông báo với
525hoạt động khi nào thì một mục danh sách được chọn để nó có thể yêu cầu phân đoạn B hiển thị bài viết đó. Trong
526trường hợp này, giao diện {@code OnArticleSelectedListener} sẽ được khai báo bên trong phân đoạn A:</p>
527
528<pre>
529public static class FragmentA extends ListFragment {
530    ...
531    // Container Activity must implement this interface
532    public interface OnArticleSelectedListener {
533        public void onArticleSelected(Uri articleUri);
534    }
535    ...
536}
537</pre>
538
539<p>Khi đó, hoạt động lưu trữ phân đoạn sẽ triển khai giao diện {@code OnArticleSelectedListener}
540541khống chế {@code onArticleSelected()} để thông báo với phân đoạn B về sự kiện từ phân đoạn A. Để đảm bảo
542rằng hoạt động chủ triển khai giao diện này, phương pháp gọi lại {@link
543android.app.Fragment#onAttach onAttach()} của phân đoạn A (mà hệ thống gọi khi thêm
544phân đoạn vào hoạt động) sẽ khởi tạo một thực thể của {@code OnArticleSelectedListener} bằng cách
545đổi kiểu {@link android.app.Activity} mà được chuyển vào {@link android.app.Fragment#onAttach
546onAttach()}:</p>
547
548<pre>
549public static class FragmentA extends ListFragment {
550    OnArticleSelectedListener mListener;
551    ...
552    &#64;Override
553    public void onAttach(Activity activity) {
554        super.onAttach(activity);
555        try {
556            mListener = (OnArticleSelectedListener) activity;
557        } catch (ClassCastException e) {
558            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
559        }
560    }
561    ...
562}
563</pre>
564
565<p>Nếu hoạt động chưa triển khai giao diện, khi đó phân đoạn sẽ đưa ra lỗi
566{@link java.lang.ClassCastException}.
567Nếu thành công, thành viên {@code mListener} giữ một tham chiếu tới triển khai
568{@code OnArticleSelectedListener}của hoạt động, sao cho phân đoạn A có thể chia sẻ sự kiện với hoạt động bằng cách gọi các phương pháp
569được định nghĩa bởi giao diện {@code OnArticleSelectedListener}. Ví dụ, nếu phân đoạn A là một
570phần mở rộng của {@link android.app.ListFragment}, mỗi lần
571người dùng nhấp vào một mục danh sách, hệ thống sẽ gọi ra {@link android.app.ListFragment#onListItemClick
572onListItemClick()} trong phân đoạn, và nó lại gọi {@code onArticleSelected()} để chia sẻ
573sự kiện với hoạt động:</p>
574
575<pre>
576public static class FragmentA extends ListFragment {
577    OnArticleSelectedListener mListener;
578    ...
579    &#64;Override
580    public void onListItemClick(ListView l, View v, int position, long id) {
581        // Append the clicked item's row ID with the content provider Uri
582        Uri noteUri = ContentUris.{@link android.content.ContentUris#withAppendedId withAppendedId}(ArticleColumns.CONTENT_URI, id);
583        // Send the event and Uri to the host activity
584        mListener.onArticleSelected(noteUri);
585    }
586    ...
587}
588</pre>
589
590<p>Tham số {@code id} được chuyển vào {@link
591android.app.ListFragment#onListItemClick onListItemClick()} là ID hàng của mục được nhấp,
592nó được sử dụng bởi hoạt động (hoặc phân đoạn kia) để tải bài viết từ {@link
593android.content.ContentProvider} của ứng dụng.</p>
594
595<p><!--To see a complete implementation of this kind of callback interface, see the <a
596href="{@docRoot}resources/samples/NotePad/index.html">NotePad sample</a>. -->Bạn có thể xem thêm thông tin về
597cách sử dụng một trình cung cấp nội dung trong tài liệu <a href="{@docRoot}guide/topics/providers/content-providers.html">Trình cung cấp Nội dung</a>.</p>
598
599
600
601<h3 id="ActionBar">Thêm mục vào Thanh Hành động</h3>
602
603<p>Phân đoạn của bạn có thể đóng góp các mục menu vào <a href="{@docRoot}guide/topics/ui/menus.html#options-menu">Menu Tùy chọn</a> của hoạt động (và tiếp đó là cả <a href="{@docRoot}guide/topics/ui/actionbar.html">Thanh Hành động</a>) bằng cách triển khai
604{@link android.app.Fragment#onCreateOptionsMenu(Menu,MenuInflater) onCreateOptionsMenu()}. Tuy nhiên, để
605phương pháp này nhận lệnh gọi, bạn phải gọi {@link
606android.app.Fragment#setHasOptionsMenu(boolean) setHasOptionsMenu()} trong khi {@link
607android.app.Fragment#onCreate(Bundle) onCreate()}, để cho biết rằng phân đoạn
608sẽ muốn thêm mục vào Menu Tùy chọn (nếu không, phân đoạn sẽ không nhận được lệnh gọi tới
609{@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()}).</p>
610
611<p>Bất kỳ mục nào mà bạn thêm vào Menu Tùy chọn sau đó từ phân đoạn đều được nối với các mục menu
612hiện tại. Phân đoạn cũng nhận các lệnh gọi lại tới {@link
613android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} khi một mục menu
614được chọn.</p>
615
616<p>Bạn cũng có thể đăng ký một dạng xem trong bố trí phân đoạn của mình để cung cấp một menu ngữ cảnh bằng cách gọi {@link
617android.app.Fragment#registerForContextMenu(View) registerForContextMenu()}. Khi người dùng mở
618menu ngữ cảnh, phân đoạn nhận một lệnh gọi tới {@link
619android.app.Fragment#onCreateContextMenu(ContextMenu,View,ContextMenu.ContextMenuInfo)
620onCreateContextMenu()}. Khi người dùng chọn một mục, phân đoạn nhận được một lệnh gọi tới {@link
621android.app.Fragment#onContextItemSelected(MenuItem) onContextItemSelected()}.</p>
622
623<p class="note"><strong>Lưu ý:</strong> Mặc dù phân đoạn của bạn nhận được một lệnh gọi khi chọn mục
624đối với từng mục menu mà nó thêm, trước tiên hoạt động sẽ nhận phương pháp gọi lại tương ứng khi người dùng
625chọn một mục menu. Nếu việc triển khai gọi lại khi chọn mục của hoạt động không
626xử lý mục được chọn, khi đó sự kiện được chuyển sang phương pháp gọi lại của phân đoạn. Điều này đúng đối với
627Menu Tùy chọn và các menu ngữ cảnh.</p>
628
629<p>Để biết thêm thông tin về các menu, xem các hướng dẫn cho nhà phát triển <a href="{@docRoot}guide/topics/ui/menus.html">Menu</a> và <a href="{@docRoot}guide/topics/ui/actionbar.html">Thanh Hành động</a>.</p>
630
631
632
633
634<h2 id="Lifecycle">Xử lý Vòng đời của Phân đoạn</h2>
635
636<div class="figure" style="width:350px">
637<img src="{@docRoot}images/activity_fragment_lifecycle.png" alt="" />
638<p class="img-caption"><strong>Hình 3.</strong> Ảnh hưởng của vòng đời hoạt động tới vòng đời
639của phân đoạn.</p>
640</div>
641
642<p>Việc quản lý vòng đời của một phân đoạn rất giống với quản lý vòng đời của một hoạt động. Giống như
643hoạt động, phân đoạn có thể tồn tại ở ba trạng thái:</p>
644
645<dl>
646  <dt><i>Tiếp tục</i></dt>
647    <dd>Phân đoạn hiển thị trong hoạt động đang chạy.</dd>
648
649  <dt><i>Tạm dừng</i></dt>
650    <dd>Một hoạt động khác ở trong tiền cảnh và có tiêu điểm, nhưng hoạt động mà phân đoạn
651này nằm trong vẫn hiển thị (hoạt động tiền cảnh mờ một phần hoặc không
652che phủ toàn bộ màn hình).</dd>
653
654  <dt><i>Dừng</i></dt>
655    <dd>Phân đoạn không hiển thị. Hoặc là hoạt động chủ đã bị dừng hoặc
656phân đoạn đã được gỡ bỏ khỏi hoạt động, nhưng được thêm vào ngăn xếp. Phân đoạn dừng
657vẫn còn hoạt động (tất cả thông tin về trạng thái và thành viên đều được hệ thống giữ lại). Tuy nhiên, nó không còn
658hiển thị với người dùng nữa và sẽ bị tắt bỏ nếu hoạt động bị tắt bỏ.</dd>
659</dl>
660
661<p>Cũng như một hoạt động, bạn có thể giữ lại trạng thái của một phân đoạn bằng cách sử dụng {@link
662android.os.Bundle}, trong trường hợp tiến trình của hoạt động bị tắt bỏ và bạn cần khôi phục
663trạng thái của phân đoạn khi hoạt động được tạo lại. Bạn có thể lưu trạng thái trong phương pháp gọi lại {@link
664android.app.Fragment#onSaveInstanceState onSaveInstanceState()} của phân đoạn và khôi phục nó trong
665hoặc {@link android.app.Fragment#onCreate onCreate()}, {@link
666android.app.Fragment#onCreateView onCreateView()}, hoặc {@link
667android.app.Fragment#onActivityCreated onActivityCreated()}. Để biết thêm thông tin về việc lưu
668trạng thái, xem tài liệu <a href="{@docRoot}guide/components/activities.html#SavingActivityState">Hoạt động</a>
669.</p>
670
671<p>Sự khác nhau quan trọng nhất trong vòng đời giữa một hoạt động và một phân đoạn đó là cách chúng
672được lưu trữ trong ngăn xếp tương ứng. Hoạt động được đặt vào một ngăn xếp gồm nhiều hoạt động
673, được quản lý bởi hệ thống theo mặc định khi bị dừng (sao cho người dùng có thể điều hướng lại
674nó bằng nút <em>Quay lại</em> như được đề cập trong <a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tác vụ và Ngăn xếp</a>).
675Tuy nhiên, phân đoạn chỉ được đặt vào một ngăn xếp do hoạt động chủ quản lý khi bạn
676yêu cầu rõ ràng rằng trường hợp đó phải được lưu bằng cách gọi {@link
677android.app.FragmentTransaction#addToBackStack(String) addToBackStack()} trong một giao tác
678gỡ bỏ phân đoạn.</p>
679
680<p>Nếu không thì việc quản lý vòng đời của phân đoạn rất giống với việc quản lý vòng đời
681của hoạt động. Vì thế, những nội dung áp dụng cho <a href="{@docRoot}guide/components/activities.html#Lifecycle">quản lý vòng đời của
682hoạt động</a> cũng áp dụng cho phân đoạn. Tuy nhiên, việc mà bạn cũng cần phải hiểu đó là cách
683vòng đời của hoạt động ảnh hưởng tới vòng đời của phân đoạn.</p>
684
685<p class="caution"><strong>Chú ý:</strong> Nếu bạn cần một đối tượng {@link android.content.Context} trong
686{@link android.app.Fragment}của mình, bạn có thể gọi {@link android.app.Fragment#getActivity()}.
687Tuy nhiên, nhớ chỉ được gọi {@link android.app.Fragment#getActivity()} khi phân đoạn được gắn với
688một hoạt động. Khi phân đoạn chưa được gắn, hoặc bị gỡ trong khi kết thúc
689vòng đời của nó, {@link android.app.Fragment#getActivity()} sẽ trả về rỗng.</p>
690
691
692<h3 id="CoordinatingWithActivity">Phối hợp với vòng đời của hoạt động</h3>
693
694<p>Vòng đời của hoạt động mà phân đoạn có ở trong đó sẽ trực tiếp ảnh hưởng tới vòng đời của phân đoạn
695, sao cho mỗi lệnh gọi lại vòng đời cho hoạt động đó sẽ dẫn tới một lệnh gọi lại tương tự cho từng
696phân đoạn. Ví dụ, khi hoạt động nhận được {@link android.app.Activity#onPause}, mỗi
697phân đoạn trong hoạt động sẽ nhận được {@link android.app.Fragment#onPause}.</p>
698
699<p>Tuy nhiên, các phân đoạn có thêm một vài lệnh gọi lại vòng đời nhằm xử lý tương tác duy nhất với
700hoạt động để thực hiện các hành động như xây dựng và hủy UI của phân đoạn. Những phương pháp gọi lại
701bổ sung này là:</p>
702
703<dl>
704  <dt>{@link android.app.Fragment#onAttach onAttach()}</dt>
705    <dd>Được gọi khi phân đoạn đã được liên kết với hoạt động {@link
706android.app.Activity} được chuyển ở đây).</dd>
707  <dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt>
708    <dd>Được gọi khi tạo phân cấp dạng xem được liên kết với phân đoạn.</dd>
709  <dt>{@link android.app.Fragment#onActivityCreated onActivityCreated()}</dt>
710    <dd>Được gọi khi phương pháp {@link android.app.Activity#onCreate
711onCreate()} của hoạt động đã trả về.</dd>
712  <dt>{@link android.app.Fragment#onDestroyView onDestroyView()}</dt>
713    <dd>Được gọi khi phân cấp dạng xem được liên kết với phân đoạn đang được gỡ bỏ.</dd>
714  <dt>{@link android.app.Fragment#onDetach onDetach()}</dt>
715    <dd>Được gọi khi phân đoạn đang được bỏ liên kết khỏi hoạt động.</dd>
716</dl>
717
718<p>Tiến trình vòng đời của một phân đoạn, do bị ảnh hưởng bởi hoạt động chủ của nó, được minh họa
719bởi hình 3. Trong hình này, bạn có thể thấy cách thức mỗi trạng thái nối tiếp nhau của hoạt động sẽ xác định
720các phương pháp gọi lại nào mà một phân đoạn có thể nhận được. Ví dụ, khi hoạt động đã nhận được lệnh gọi lại {@link
721android.app.Activity#onCreate onCreate()} của nó, phân đoạn trong hoạt động sẽ nhận được không quá
722lệnh gọi lại {@link android.app.Fragment#onActivityCreated onActivityCreated()}.</p>
723
724<p>Sau khi hoạt động đạt trạng thái tiếp tục, bạn có thể tự do thêm và gỡ bỏ phân đoạn vào
725hoạt động. Vì thế, chỉ trong khi hoạt động ở trạng thái tiếp tục thì vòng đời của một phân đoạn
726mới có thể thay đổi độc lập.</p>
727
728<p>Tuy nhiên, khi hoạt động rời khỏi trạng thái tiếp tục, phân đoạn lại bị hoạt động đẩy qua vòng đời
729của mình.</p>
730
731
732
733
734<h2 id="Example">Ví dụ</h2>
735
736<p>Để kết hợp mọi nội dung được đề cập trong tài liệu này, sau đây là một ví dụ về hoạt động
737sử dụng hai phân đoạn để tạo một bố trí hai bảng. Hoạt động bên dưới bao gồm một phân đoạn để
738hiển thị danh sách các vở kịch của Shakespeare và một phân đoạn khác để hiển thị tóm tắt về vở kịch khi được chọn
739từ danh sách. Nó cũng minh họa cách cung cấp các cấu hình phân đoạn khác nhau,
740dựa trên cấu hình màn hình.</p>
741
742<p class="note"><strong>Lưu ý:</strong> Mã nguồn hoàn chỉnh cho hoạt động này có sẵn trong
743<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.html">{@code
744FragmentLayout.java}</a>.</p>
745
746<p>Hoạt động chính áp dụng một bố trí theo cách thông thường, trong {@link
747android.app.Activity#onCreate onCreate()}:</p>
748
749{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java main}
750
751<p>Bố trí được áp dụng là {@code fragment_layout.xml}:</p>
752
753{@sample development/samples/ApiDemos/res/layout-land/fragment_layout.xml layout}
754
755<p>Khi sử dụng bố trí này, hệ thống sẽ khởi tạo {@code TitlesFragment} (liệt kê tên
756các vở kịch) ngay khi hoạt động nạp bố trí, trong khi {@link android.widget.FrameLayout}
757(nơi sẽ xuất hiện phân đoạn hiển thị tóm tắt về vở kịch) chiếm khoảng trống phía bên phải của
758màn hình, nhưng ban đầu vẫn trống. Như bạn sẽ thấy bên dưới, mãi tới khi người dùng chọn một mục
759từ danh sách thì một phân đoạn mới được đặt vào {@link android.widget.FrameLayout}.</p>
760
761<p>Tuy nhiên, không phải tất cả cấu hình màn hình đều đủ rộng để hiển thị cả danh sách
762các vở kịch và tóm tắt bên cạnh nhau. Vì thế, bố trí trên chỉ được sử dụng cho cấu hình
763màn hình khổ ngang bằng cách lưu nó dưới dạng {@code res/layout-land/fragment_layout.xml}.</p>
764
765<p>Vì thế, khi màn hình hướng đứng, hệ thống sẽ áp dụng bố trí sau, nó
766được lưu tại {@code res/layout/fragment_layout.xml}:</p>
767
768{@sample development/samples/ApiDemos/res/layout/fragment_layout.xml layout}
769
770<p>Bố trí này chỉ bao gồm {@code TitlesFragment}. Điều này có nghĩa là, khi thiết bị ở
771hướng đứng, chỉ danh sách tên vở kịch được hiển thị. Vì thế, khi người dùng nhấp vào một
772mục danh sách trong cấu hình này, ứng dụng sẽ bắt đầu một hoạt động mới để hiển thị tóm tắt,
773thay vì tải một phân đoạn thứ hai.</p>
774
775<p>Tiếp theo, bạn có thể thấy cách hoàn thành điều này trong các lớp phân đoạn. Đầu tiên là {@code
776TitlesFragment}, hiển thị danh sách tên các vở kịch của Shakespeare. Phân đoạn này sẽ mở rộng {@link
777android.app.ListFragment} và dựa vào nó để xử lý hầu hết công việc về dạng xem danh sách.</p>
778
779<p>Khi bạn kiểm tra đoạn mã này, hãy để ý rằng có hai hành vi có thể khi người dùng nhấp vào một
780mục danh sách: phụ thuộc vào bố trí nào trong hai bố trí đang hiện hoạt, nó có thể hoặc tạo và hiển thị một phân đoạn
781mới để hiển thị chi tiết trong cùng hoạt động (thêm phân đoạn vào {@link
782android.widget.FrameLayout}), hoặc bắt đầu một hoạt động mới (tại đó phân đoạn có thể được hiển thị).</p>
783
784{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java titles}
785
786<p>Phân đoạn thứ hai, {@code DetailsFragment} sẽ hiển thị tóm tắt vở kịch cho mục được chọn từ
787danh sách trong {@code TitlesFragment}:</p>
788
789{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java details}
790
791<p>Nhớ lại ở lớp {@code TitlesFragment} rằng, nếu người dùng nhấp vào một mục danh sách và bố trí
792hiện tại <em>không</em> có dạng xem {@code R.id.details} (là nơi mà
793{@code DetailsFragment} thuộc về), khi đó, ứng dụng sẽ bắt đầu hoạt động {@code DetailsActivity}
794để hiển thị nội dung của mục đó.</p>
795
796<p>Sau đây là {@code DetailsActivity}, nó chỉ đơn thuần nhúng {@code DetailsFragment} để hiển thị
797tóm tắt vở kịch được chọn khi màn hình ở hướng đứng:</p>
798
799{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
800details_activity}
801
802<p>Lưu ý rằng hoạt động này tự kết thúc nếu cấu hình là khổ ngang, sao cho hoạt động
803chính có thể chiếm lấy và hiển thị {@code DetailsFragment} bên cạnh {@code TitlesFragment}.
804Điều này có thể xảy ra nếu người dùng bắt đầu {@code DetailsActivity} ở dạng hướng đứng, nhưng
805sau đó xoay thành khổ ngang (làm vậy sẽ bắt đầu lại hoạt động hiện tại).</p>
806
807
808<p>Để biết thêm mẫu sử dụng phân đoạn (và toàn bộ tệp nguồn cho ví dụ này),
809hãy xem ứng dụng mẫu API Demos có sẵn trong <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment">
810ApiDemos</a> (có thể tải xuống từ <a href="{@docRoot}resources/samples/get.html">Thành phần SDK Mẫu</a>).</p>
811
812
813