• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Menu
2parent.title=Giao diện Người dùng
3parent.link=index.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="#xml">Định nghĩa một Menu trong XML</a></li>
11  <li><a href="#options-menu">Tạo một Menu Tùy chọn</a>
12    <ol>
13      <li><a href="#RespondingOptionsMenu">Xử lý sự kiện nhấp</a></li>
14      <li><a href="#ChangingTheMenu">Thay đổi các mục menu vào thời gian chạy</a></li>
15    </ol>
16  </li>
17  <li><a href="#context-menu">Tạo một Menu Ngữ cảnh</a>
18    <ol>
19      <li><a href="#FloatingContextMenu">Tạo một menu ngữ cảnh nổi</a></li>
20      <li><a href="#CAB">Sử dụng chế độ hành động theo ngữ cảnh</a></li>
21    </ol>
22  </li>
23  <li><a href="#PopupMenu">Tạo một Menu Bật lên</a>
24    <ol>
25      <li><a href="#PopupEvents">Xử lý sự kiện nhấp</a></li>
26    </ol>
27  </li>
28  <li><a href="#groups">Tạo Nhóm Menu</a>
29    <ol>
30      <li><a href="#checkable">Sử dụng mục menu có thể chọn</a></li>
31    </ol>
32  </li>
33  <li><a href="#intents">Thêm Mục Menu dựa trên Ý định</a>
34    <ol>
35      <li><a href="#AllowingToAdd">Cho phép hoạt động của bạn được thêm vào các menu khác</a></li>
36    </ol>
37  </li>
38</ol>
39
40  <h2>Lớp khóa</h2>
41  <ol>
42    <li>{@link android.view.Menu}</li>
43    <li>{@link android.view.MenuItem}</li>
44    <li>{@link android.view.ContextMenu}</li>
45    <li>{@link android.view.ActionMode}</li>
46  </ol>
47
48  <h2>Xem thêm</h2>
49  <ol>
50    <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Thanh Hành động</a></li>
51    <li><a href="{@docRoot}guide/topics/resources/menu-resource.html">Tài nguyên Menu</a></li>
52    <li><a href="http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html">Nói
53Tạm biệt với Nút Menu</a></li>
54  </ol>
55</div>
56</div>
57
58<p>Menu là một thành phần giao diện người dùng phổ biến trong nhiều loại ứng dụng. Để cung cấp một
59trải nghiệm người dùng quen thuộc và nhất quán, bạn nên sử dụng các API {@link android.view.Menu} để trình bày
60hành động người dùng và các tùy chọn khác trong hoạt động của mình.</p>
61
62<p>Bắt đầu với Android 3.0 (API mức 11), các thiết bị dựa trên nền tảng Android không còn phải
63cung cấp một nút <em>Menu</em> chuyên dụng nữa. Với sự thay đổi này, các ứng dụng Android cần tránh khỏi
64sự phụ thuộc vào bảng điều khiển menu 6 mục truyền thống này mà thay vào đó cung cấp một thanh hành động để trình bày
65các hành động người dùng thông dụng.</p>
66
67<p>Mặc dù thiết kế và trải nghiệm người dùng đối với một số mục menu đã thay đổi, ngữ nghĩa để định nghĩa
68tập hợp hành động và tùy chọn thì vẫn dựa trên các API {@link android.view.Menu}. Hướng dẫn
69này trình bày cách tạo ba loại menu hay trình bày hành động cơ bản trên tất cả
70phiên bản Android:</p>
71
72<dl>
73  <dt><strong>Menu tùy chọn và thanh hành động</strong></dt>
74    <dd><a href="#options-menu">Menu tùy chọn</a> là tập hợp các mục menu cơ bản cho một
75hoạt động. Đó là nơi bạn nên đặt các hành động có tác động chung tới ứng dụng, chẳng hạn như
76"Tìm kiếm," "Soạn e-mail" và "Cài đặt."
77  <p>Nếu bạn đang phát triển cho phiên bản Android 2.3 hoặc thấp hơn, người dùng có thể
78hiện bảng điều khiển menu tùy chọn bằng cách nhấn nút <em>Menu</em>.</p>
79  <p>Trên phiên bản Android 3.0 trở lên, các mục từ menu tùy chọn được trình bày bởi <a href="{@docRoot}guide/topics/ui/actionbar.html">thanh hành động</a>, là sự kết hợp giữa các mục hành động
80trên màn hình và các tùy chọn tràn. Bắt đầu với phiên bản Android 3.0, nút <em>Menu</em> bị bỏ đi (một số
81thiết bị
82không có), vì thế bạn nên chuyển sang sử dụng thanh hành động để cho phép truy cập vào hành động và
83các tùy chọn khác.</p>
84  <p>Xem phần về <a href="#options-menu">Tạo một Menu Tùy chọn</a>.</p>
85    </dd>
86
87  <dt><strong>Menu ngữ cảnh và chế độ hành động theo ngữ cảnh</strong></dt>
88
89   <dd>Menu ngữ cảnh là một <a href="#FloatingContextMenu">menu nổi</a> xuất hiện khi
90người dùng thực hiện nhấp giữ trên một phần tử. Nó cung cấp các hành động ảnh hưởng tới nội dung hoặc
91khung ngữ cảnh được chọn.
92  <p>Khi phát triển cho phiên bản Android 3.0 trở lên, thay vào đó, bạn nên sử dụng <a href="#CAB">chế độ hành động theo ngữ cảnh</a> để kích hoạt các hành động trên nội dung được chọn. Chế độ này hiển thị
93các mục hành động ảnh hưởng tới nội dung được chọn trong một thanh ở trên cùng của màn hình và cho phép người dùng
94chọn nhiều mục.</p>
95  <p>Xem phần nói về <a href="#context-menu">Tạo Menu Ngữ cảnh</a>.</p>
96</dd>
97
98  <dt><strong>Menu bật lên</strong></dt>
99    <dd>Menu bật lên sẽ hiển thị danh sách các mục trong một danh sách thẳng đứng được neo vào dạng xem
100đã gọi ra menu. Nên cung cấp một phần tràn gồm các hành động liên quan tới nội dung cụ thể hoặc
101nhằm cung cấp các tùy chọn cho phần thứ hai của một lệnh. Các hành động trong một menu bật lên
102<strong>không</strong> nên trực tiếp ảnh hưởng tới nội dung tương ứng&mdash;đó là việc của hành động ngữ cảnh
103. Thay vào đó, menu bật lên áp dụng cho các hành động mở rộng liên quan tới các vùng nội dung trong hoạt động
104của bạn.
105  <p>Xem phần về <a href="#PopupMenu">Tạo một Menu Bật lên</a>.</p>
106</dd>
107</dl>
108
109
110
111<h2 id="xml">Định nghĩa một Menu trong XML</h2>
112
113<p>Đối với tất cả các loại menu, Android cung cấp một định dạng XML chuẩn để định nghĩa các mục menu.
114Thay vì xây dựng một menu trong mã của hoạt động của bạn, bạn nên định nghĩa một menu và tất cả các mục của nó trong một
115<a href="{@docRoot}guide/topics/resources/menu-resource.html">tài nguyên menu</a> XML. Khi đó, bạn có thể
116bung tài nguyên menu (tải nó như một đối tượng {@link android.view.Menu}) trong hoạt động hoặc
117phân đoạn của mình.</p>
118
119<p>Sử dụng một tài nguyên menu là một cách làm hay vì một vài lý do:</p>
120<ul>
121  <li>Nó dễ trực quan hóa cấu trúc menu trong XML hơn.</li>
122  <li>Nó tách riêng nội dung cho menu với mã hành vi của ứng dụng của bạn.</li>
123  <li>Nó cho phép bạn tạo các cấu hình menu phái sinh cho các phiên bản nền tảng,
124kích cỡ màn hình khác nhau và các cấu hình khác bằng cách tận dụng khuôn khổ <a href="{@docRoot}guide/topics/resources/index.html">tài nguyên ứng dụng</a>.</li>
125</ul>
126
127<p>Để định nghĩa menu, hãy tạo một tệp XML bên trong thư mục <code>res/menu/</code>
128dự án của bạn và xây dựng menu với các phần tử sau:</p>
129<dl>
130  <dt><code>&lt;menu></code></dt>
131    <dd>Định nghĩa một {@link android.view.Menu}, đó là một bộ chứa các mục menu. Phần tử
132<code>&lt;menu></code> phải là một nút gốc cho tệp và có thể giữ một hoặc nhiều phần tử
133<code>&lt;item></code> và <code>&lt;group></code>.</dd>
134
135  <dt><code>&lt;item></code></dt>
136    <dd>Tạo một {@link android.view.MenuItem}, nó biểu diễn một mục đơn trong một menu. Phần tử
137này có thể chứa một phần tử <code>&lt;menu></code> được lồng nhau để tạo một menu con.</dd>
138
139  <dt><code>&lt;group></code></dt>
140    <dd>Một bộ chứa tùy chọn, vô hình cho các phần tử {@code &lt;item&gt;}. Nó cho phép bạn
141phân loại các mục menu sao cho chúng chia sẻ các tính chất như trạng thái hiện hoạt và khả năng hiển thị. Để biết thêm
142thông tin, hãy xem phần nói về <a href="#groups">Tạo Nhóm Menu</a>.</dd>
143</dl>
144
145
146<p>Sau đây là một menu ví dụ có tên là <code>game_menu.xml</code>:</p>
147<pre>
148&lt;?xml version="1.0" encoding="utf-8"?&gt;
149&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
150    &lt;item android:id="@+id/new_game"
151          android:icon="@drawable/ic_new_game"
152          android:title="@string/new_game"
153          android:showAsAction="ifRoom"/&gt;
154    &lt;item android:id="@+id/help"
155          android:icon="@drawable/ic_help"
156          android:title="@string/help" /&gt;
157&lt;/menu&gt;
158</pre>
159
160<p>Phần tử <code>&lt;item></code> hỗ trợ một vài thuộc tính bạn có thể sử dụng để định nghĩa biểu hiện bên ngoài
161và hành vi của một mục. Các mục trong menu trên bao gồm những thuộc tính sau:</p>
162
163<dl>
164  <dt>{@code android:id}</dt>
165    <dd>Một ID tài nguyên duy nhất đối với mục, nó cho phép ứng dụng có thể nhận ra mục đó
166khi người dùng chọn nó.</dd>
167  <dt>{@code android:icon}</dt>
168    <dd>Một tham chiếu tới một nội dung vẽ được để dùng làm biểu tượng của mục.</dd>
169  <dt>{@code android:title}</dt>
170    <dd>Một tham chiếu tới một xâu để dùng làm tiêu đề của mục.</dd>
171  <dt>{@code android:showAsAction}</dt>
172    <dd>Quy định thời điểm và cách thức mục này nên xuất hiện như một mục hành động trong <a href="{@docRoot}guide/topics/ui/actionbar.html">thanh hành động</a>.</dd>
173</dl>
174
175<p>Đây là những thuộc tính quan trọng nhất bạn nên sử dụng, nhưng còn nhiều thuộc tính sẵn có khác.
176Để biết thông tin về tất cả thuộc tính được hỗ trợ, hãy xem tài liệu <a href="{@docRoot}guide/topics/resources/menu-resource.html">Tài nguyên Menu</a>.</p>
177
178<p>Bạn có thể thêm một menu con vào một mục trong bất kỳ menu nào (ngoại trừ menu con) bằng cách thêm một phần tử {@code &lt;menu&gt;}
179làm con của {@code &lt;item&gt;}. Các menu con thường hữu ích khi ứng dụng của bạn có nhiều
180chức năng mà có thể được tổ chức thành các chủ đề, như các mục trong thanh menu của một ứng dụng PC (Tệp,
181Chỉnh sửa, Dạng xem, v.v.). Ví dụ:</p>
182
183<pre>
184&lt;?xml version="1.0" encoding="utf-8"?&gt;
185&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
186    &lt;item android:id="@+id/file"
187          android:title="@string/file" &gt;
188        &lt;!-- "file" submenu --&gt;
189        &lt;menu&gt;
190            &lt;item android:id="@+id/create_new"
191                  android:title="@string/create_new" /&gt;
192            &lt;item android:id="@+id/open"
193                  android:title="@string/open" /&gt;
194        &lt;/menu&gt;
195    &lt;/item&gt;
196&lt;/menu&gt;
197</pre>
198
199<p>Để sử dụng menu trong hoạt động của mình, bạn cần bung tài nguyên menu (chuyển tài nguyên XML
200thành một đối tượng có thể lập trình) bằng cách sử dụng {@link android.view.MenuInflater#inflate(int,Menu)
201MenuInflater.inflate()}. Trong những phần sau, bạn sẽ biết cách bung một menu đối với mỗi
202loại menu.</p>
203
204
205
206<h2 id="options-menu">Tạo một Menu Tùy chọn</h2>
207
208<div class="figure" style="width:200px;margin:0">
209  <img src="{@docRoot}images/options_menu.png" height="333" alt="" />
210  <p class="img-caption"><strong>Hình 1.</strong> Các menu tùy chọn trong
211Trình duyệt, trên Android 2.3.</p>
212</div>
213
214<p>Menu tùy chọn là nơi bạn nên đưa vào hành động và các tùy chọn khác liên quan tới
215ngữ cảnh hoạt động hiện tại, chẳng hạn như "Tìm kiếm," "Soạn e-mail," và "Cài đặt."</p>
216
217<p>Nơi mà các mục trong menu tùy chọn của bạn xuất hiện trên màn hình sẽ phụ thuộc vào phiên bản mà bạn
218phát triển ứng dụng của mình cho:</p>
219
220<ul>
221  <li>Nếu bạn phát triển ứng dụng của mình cho phiên bản <strong>Android 2.3.x (API mức 10) hoặc
222thấp hơn</strong>, nội dung của menu tùy chọn sẽ xuất hiện ở dưới cùng màn hình khi người dùng
223nhấn nút <em>Menu</em> như minh họa trong hình 1. Khi được mở, phần hiển thị đầu tiên là
224menu biểu tượng
225với tối đa sáu mục menu. Nếu menu của bạn bao gồm nhiều hơn sáu mục, Android sẽ đặt
226mục thứ sáu và phần còn lại vào một menu tràn mà người dùng có thể mở bằng cách chọn
227<em>Thêm nữa</em>.</li>
228
229  <li>Nếu bạn phát triển ứng dụng của mình cho phiên bản <strong>Android 3.0 (API mức 11) và
230cao hơn</strong>, các mục từ menu tùy chọn sẵn ở trong <a href="{@docRoot}guide/topics/ui/actionbar.html">thanh hành động</a>. Theo mặc định, hệ thống
231đặt tất cả các mục trong phần tràn hành động mà người dùng có thể hiện bằng biểu tượng tràn hành động phía
232bên phải của thanh hành động (hoặc bằng cách nhấn nút <em>Menu</em> của thiết bị nếu có). Để
233kích hoạt
234truy cập nhanh vào các hành động quan trọng, bạn có thể đưa lên một vài mục xuất hiện trong thanh hành động bằng cách thêm
235{@code android:showAsAction="ifRoom"} vào phần tử {@code &lt;item&gt;} tương ứng (xem hình
2362). <p>Để biết thêm thông tin về các mục hành động và hành vi khác của thanh hành động, hãy xem hướng dẫn <a href="{@docRoot}guide/topics/ui/actionbar.html">Thanh Hành động</a>. </p>
237<p class="note"><strong>Lưu ý:</strong> Ngay cả khi bạn <em>không</em> đang phát triển cho phiên bản Android 3.0 hoặc
238cao hơn, bạn có thể xây dựng bố trí thanh hành động của chính mình cho hiệu ứng tương tự. Để xem ví dụ về cách bạn có thể hỗ trợ các phiên bản cao hơn
239của Android bằng một thanh hành động, hãy xem mẫu <a href="{@docRoot}resources/samples/ActionBarCompat/index.html">Tương thích với Thanh Hành động</a>
240.</p>
241</li>
242</ul>
243
244<img src="{@docRoot}images/ui/actionbar.png" alt="" />
245<p class="img-caption"><strong>Hình 2.</strong> Thanh hành động từ ứng dụng <a href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a>, hiển thị
246các tab điều hướng và một mục hành động máy ảnh (cộng với nút tràn hành động).</p>
247
248<p>Bạn có thể khai báo các mục cho menu tùy chọn từ lớp con {@link android.app.Activity}
249của bạn hoặc một lớp con {@link android.app.Fragment}. Nếu cả hoạt động của bạn và (các) phân đoạn
250đều khai báo các mục cho menu tùy chọn, chúng sẽ được kết hợp lại trong UI. Các mục của hoạt động xuất hiện
251trước, sau đó là các mục của từng phân đoạn theo thứ tự phân đoạn được thêm vào
252hoạt động. Nếu cần, bạn có thể sắp xếp lại các mục menu bằng thuộc tính {@code android:orderInCategory}
253trong mỗi {@code &lt;item&gt;} mà bạn cần di chuyển.</p>
254
255<p>Để quy định menu tùy chọn cho một hoạt động, hãy khống chế {@link
256android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} (các phân đoạn cung cấp
257phương pháp gọi lại {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()} của chính mình). Trong
258phương pháp này, bạn có thể bung tài nguyên menu của mình (<a href="#xml">được định nghĩa trong XML</a>) vào {@link
259android.view.Menu} được cung cấp trong phương pháp gọi lại. Ví dụ:</p>
260
261<pre>
262&#64;Override
263public boolean onCreateOptionsMenu(Menu menu) {
264    MenuInflater inflater = {@link android.app.Activity#getMenuInflater()};
265    inflater.inflate(R.menu.game_menu, menu);
266    return true;
267}
268</pre>
269
270<p>Bạn cũng có thể thêm các mục menu bằng cách sử dụng {@link android.view.Menu#add(int,int,int,int)
271add()} và truy xuất các mục bằng {@link android.view.Menu#findItem findItem()} để xem lại
272tính chất của chúng bằng các API {@link android.view.MenuItem}.</p>
273
274<p>Nếu bạn phát triển ứng dụng của mình cho phiên bản Android 2.3.x và thấp hơn, hệ thống gọi {@link
275android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} để tạo menu tùy chọn
276khi người dùng mở menu lần đầu tiên. Nếu bạn phát triển cho phiên bản Android 3.0 vào cao hơn,
277hệ thống sẽ gọi {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} khi
278bắt đầu hoạt động để hiển thị các mục cho thanh hành động.</p>
279
280
281
282<h3 id="RespondingOptionsMenu">Xử lý sự kiện nhấp</h3>
283
284<p>Khi người dùng chọn một mục từ menu tùy chọn (bao gồm các mục hành động trong thanh hành động),
285hệ thống sẽ gọi phương pháp {@link android.app.Activity#onOptionsItemSelected(MenuItem)
286onOptionsItemSelected()} của hoạt động của bạn. Phương pháp này thông qua {@link android.view.MenuItem} được chọn. Bạn
287có thể nhận biết mục bằng cách gọi {@link android.view.MenuItem#getItemId()}, nó trả về ID duy nhất
288cho mục menu (được định nghĩa bởi thuộc tính {@code android:id} trong tài nguyên menu hoặc bằng một
289số nguyên được cấp cho phương pháp {@link android.view.Menu#add(int,int,int,int) add()}). Bạn có thể khớp
290ID này với các mục menu đã biết để thực hiện hành động phù hợp. Ví dụ:</p>
291
292<pre>
293&#64;Override
294public boolean onOptionsItemSelected(MenuItem item) {
295    // Handle item selection
296    switch (item.getItemId()) {
297        case R.id.new_game:
298            newGame();
299            return true;
300        case R.id.help:
301            showHelp();
302            return true;
303        default:
304            return super.onOptionsItemSelected(item);
305    }
306}
307</pre>
308
309<p>Khi bạn xử lý thành công một mục menu, trả về {@code true}. Nếu không xử lý được
310mục menu, bạn nên gọi triển khai siêu lớp của {@link
311android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} (triển khai
312mặc định trả về sai).</p>
313
314<p>Nếu hoạt động của bạn bao gồm các phân đoạn, trước tiên hệ thống sẽ gọi {@link
315android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} cho hoạt động, rồi mới
316cho từng phân đoạn (theo thứ tự thêm phân đoạn) tới khi trả về
317{@code true} hoặc tất cả phân đoạn đều được gọi.</p>
318
319<p class="note"><strong>Mẹo:</strong> Android 3.0 thêm khả năng cho phép bạn định nghĩa hành vi
320khi nhấp đối với một mục menu trong XML, bằng cách sử dụng thuộc tính {@code android:onClick}. Giá trị cho
321thuộc tính phải là tên của một phương pháp được định nghĩa bởi hoạt động sử dụng menu. Phương pháp
322phải công khai và chấp nhận một tham số {@link android.view.MenuItem} đơn&mdash;khi hệ thống
323gọi phương pháp này, nó thông qua mục menu được chọn. Để biết thêm thông tin và ví dụ, hãy xem tài liệu <a href="{@docRoot}guide/topics/resources/menu-resource.html">Tài nguyên Menu</a>.</p>
324
325<p class="note"><strong>Mẹo:</strong> Nếu ứng dụng của bạn chứa nhiều hoạt động và
326một số chúng cung cấp menu tùy chọn tương tự, hãy xem xét tạo
327 một hoạt động chỉ triển khai các phương pháp {@link android.app.Activity#onCreateOptionsMenu(Menu)
328onCreateOptionsMenu()} và {@link android.app.Activity#onOptionsItemSelected(MenuItem)
329onOptionsItemSelected()}. Sau đó, mở rộng lớp này đối với mỗi hoạt động cần chia sẻ
330menu tùy chọn tương tự. Bằng cách này, bạn có thể quản lý một bộ mã để xử lý các hành động
331menu và từng lớp hậu duệ kế thừa các hành vi menu.
332Nếu bạn muốn thêm các mục menu vào một trong các hoạt động hậu duệ,
333hãy khống chế {@link android.app.Activity#onCreateOptionsMenu(Menu)
334onCreateOptionsMenu()} trong hoạt động đó. Gọi {@code super.onCreateOptionsMenu(menu)} sao cho
335các mục menu gốc được tạo, sau đó thêm các mục menu mới bằng {@link
336android.view.Menu#add(int,int,int,int) menu.add()}. Bạn cũng có thể khống chế hành vi
337của siêu lớp đối với các mục menu riêng lẻ.</p>
338
339
340<h3 id="ChangingTheMenu">Thay đổi các mục menu vào thời gian chạy</h3>
341
342<p>Sau khi hệ thống gọi {@link android.app.Activity#onCreateOptionsMenu(Menu)
343onCreateOptionsMenu()}, nó sẽ giữ lại một thực thể của {@link android.view.Menu} mà bạn đưa vào và
344sẽ không gọi lại {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}
345trừ khi menu bị vô hiệu hóa vì lý do nào đó. Tuy nhiên, bạn chỉ nên sử dụng {@link
346android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} để tạo trạng thái menu
347ban đầu chứ không phải để thực hiện thay đổi trong vòng đời của hoạt động.</p>
348
349<p>Nếu bạn muốn sửa đổi menu tùy chọn dựa trên
350các sự kiện xảy ra trong vòng đời của hoạt động, bạn có thể làm vậy trong phương pháp
351 {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}. Phương pháp
352này chuyển cho bạn đối tượng {@link android.view.Menu} như hiện đang có để bạn có thể sửa đổi nó,
353chẳng hạn như thêm, xóa bỏ, hoặc vô hiệu hóa các mục. (Phân đoạn cũng cung cấp lệnh gọi lại {@link
354android.app.Fragment#onPrepareOptionsMenu onPrepareOptionsMenu()}.)</p>
355
356<p>Trên phiên bản Android 2.3.x và thấp hơn, hệ thống gọi {@link
357android.app.Activity#onPrepareOptionsMenu(Menu)
358onPrepareOptionsMenu()} mỗi lần người dùng mở menu tùy chọn (nhấn nút <em>Menu</em>
359).</p>
360
361<p>Trên phiên bản Android 3.0 trở lên, menu tùy chọn được coi như luôn mở khi các mục menu được
362trình bày trong thanh hành động. Khi một sự kiện xảy ra và bạn muốn thực hiện một cập nhật menu, bạn phải
363gọi {@link android.app.Activity#invalidateOptionsMenu invalidateOptionsMenu()} để yêu cầu
364hệ thống gọi {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}.</p>
365
366<p class="note"><strong>Lưu ý:</strong>
367Bạn không nên thay đổi các mục trong menu tùy chọn dựa trên {@link android.view.View} đang
368trong tiêu điểm. Khi ở chế độ cảm ứng (khi người dùng không sử dụng bi xoay hay d-pad), các dạng xem
369không thể lấy tiêu điểm, vì thế bạn không nên sử dụng tiêu điểm làm cơ sở để sửa đổi
370các mục trong menu tùy chọn. Nếu bạn muốn cung cấp các mục menu nhạy cảm với ngữ cảnh cho một {@link
371android.view.View}, hãy sử dụng một <a href="#context-menu">Menu Ngữ cảnh</a>.</p>
372
373
374
375
376<h2 id="context-menu">Tạo một Menu Ngữ cảnh</h2>
377
378<div class="figure" style="width:420px;margin-top:-1em">
379  <img src="{@docRoot}images/ui/menu-context.png" alt="" />
380  <p class="img-caption"><strong>Hình 3.</strong> Ảnh chụp màn hình một menu ngữ cảnh nổi (trái)
381và thanh hành động ngữ cảnh (phải).</p>
382</div>
383
384<p>Menu ngữ cảnh sẽ đưa ra các hành động ảnh hưởng tới một mục hoặc khung ngữ cảnh cụ thể trong UI. Bạn
385có thể cung cấp một menu ngữ cảnh cho bất kỳ dạng xem nào, nhưng chúng thường được sử dụng nhiều nhất cho các mục trong một {@link
386android.widget.ListView}, {@link android.widget.GridView}, hoặc các bộ sưu tập dạng xem khác mà
387người dùng có thể thực hiện hành động trực tiếp trên mỗi mục.</p>
388
389<p>Có hai cách để cung cấp các hành động ngữ cảnh:</p>
390<ul>
391  <li>Trong một <a href="#FloatingContextMenu">menu ngữ cảnh nổi</a>. Menu xuất hiện như một
392danh sách nổi gồm nhiều mục menu (tương tự như một hộp thoại) khi người dùng thực hiện nhấp giữ (nhấn và
393giữ) trên một dạng xem có khai báo hỗ trợ menu ngữ cảnh. Người dùng có thể thực hiện hành động
394ngữ cảnh trên một mục vào một thời điểm.</li>
395
396  <li>Trong <a href="#CAB">chế độ hành động theo ngữ cảnh</a>. Chế độ này là một hệ thống triển khai
397{@link android.view.ActionMode} có chức năng hiển thị một <em>thanh hành động ngữ cảnh</em> ở bên trên
398màn hình với các mục hành động ảnh hưởng tới (các) mục được chọn. Khi chế độ này hiện hoạt, người dùng
399có thể thực hiện một hành động trên nhiều mục ngay lập tức (nếu ứng dụng của bạn cho phép).</li>
400</ul>
401
402<p class="note"><strong>Lưu ý:</strong> Chế độ hành động theo ngữ cảnh sẵn có trên phiên bản Android 3.0 (API
403mức 11) và cao hơn và là kỹ thuật được ưu tiên cho việc hiển thị các hành động theo ngữ cảnh khi
404sẵn có. Nếu ứng dụng của bạn hỗ trợ các phiên bản thấp hơn 3.0, vậy bạn nên quay lại menu ngữ cảnh
405nổi trên những thiết bị đó.</p>
406
407
408<h3 id="FloatingContextMenu">Tạo một menu ngữ cảnh nổi</h3>
409
410<p>Để cung cấp một menu ngữ cảnh nổi:</p>
411<ol>
412  <li>Đăng ký {@link android.view.View} mà menu ngữ cảnh nên được liên kết với bằng cách
413gọi {@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()} và chuyển
414cho nó {@link android.view.View}.
415  <p>Nếu hoạt động của bạn sử dụng một {@link android.widget.ListView} hoặc {@link android.widget.GridView} và
416bạn muốn từng mục cung cấp cùng menu ngữ cảnh, hãy đăng ký tất cả mục cho một menu ngữ cảnh bằng cách
417chuyển {@link android.widget.ListView} hoặc {@link android.widget.GridView} cho {@link
418android.app.Activity#registerForContextMenu(View) registerForContextMenu()}.</p>
419</li>
420
421  <li>Triển khai phương pháp {@link
422android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()}
423trong {@link android.app.Activity} hoặc {@link android.app.Fragment} của bạn.
424  <p>Khi dạng xem được đăng ký nhận được một sự kiện nhấp giữ, hệ thống sẽ gọi phương pháp {@link
425android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()}
426của bạn. Đây là nơi bạn định nghĩa các mục menu, thường bằng cách bung một tài nguyên menu. Ví
427dụ:</p>
428<pre>
429&#64;Override
430public void onCreateContextMenu(ContextMenu menu, View v,
431                                ContextMenuInfo menuInfo) {
432    super.onCreateContextMenu(menu, v, menuInfo);
433    MenuInflater inflater = getMenuInflater();
434    inflater.inflate(R.menu.context_menu, menu);
435}
436</pre>
437
438<p>{@link android.view.MenuInflater} cho phép bạn bung menu ngữ cảnh từ một <a href="{@docRoot}guide/topics/resources/menu-resource.html">tài nguyên menu</a>. Các tham số của phương pháp gọi lại
439bao gồm {@link android.view.View}
440mà người dùng đã chọn và một đối tượng {@link android.view.ContextMenu.ContextMenuInfo} cung cấp
441thông tin bổ sung về mục được chọn. Nếu hoạt động của bạn có một vài dạng xem mà mỗi dạng cung cấp
442một menu ngữ cảnh khác nhau, bạn có thể sử dụng những tham số này để xác định menu ngữ cảnh nào cần
443bung.</p>
444</li>
445
446<li>Triển khai {@link android.app.Activity#onContextItemSelected(MenuItem)
447onContextItemSelected()}.
448  <p>Khi người dùng chọn một mục menu, hệ thống sẽ gọi phương pháp này để bạn có thể thực hiện
449hành động phù hợp. Ví dụ:</p>
450
451<pre>
452&#64;Override
453public boolean onContextItemSelected(MenuItem item) {
454    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
455    switch (item.getItemId()) {
456        case R.id.edit:
457            editNote(info.id);
458            return true;
459        case R.id.delete:
460            deleteNote(info.id);
461            return true;
462        default:
463            return super.onContextItemSelected(item);
464    }
465}
466</pre>
467
468<p>Phương pháp {@link android.view.MenuItem#getItemId()} sẽ truy vấn ID cho
469mục menu được chọn, bạn nên gán mục này cho từng mục menu trong XML bằng cách sử dụng thuộc tính {@code
470android:id} như trình bày trong phần về <a href="#xml">Định nghĩa một Menu trong
471XML</a>.</p>
472
473<p>Khi bạn xử lý thành công một mục menu, trả về {@code true}. Nếu bạn không xử lý mục menu,
474bạn nên chuyển mục menu đó tới triển khai siêu lớp. Nếu hoạt động của bạn bao gồm nhiều phân đoạn,
475hoạt động sẽ nhận được lệnh gọi lại này trước. Bằng cách gọi siêu lớp khi chưa được xử lý, hệ thống
476sẽ chuyển sự kiện tới phương pháp gọi lại tương ứng trong từng phân đoạn, lần lượt (theo thứ tự
477thêm phân đoạn) tới khi {@code true} hoặc {@code false} được trả về. (Triển khai
478mặc định cho {@link android.app.Activity} và {@code android.app.Fragment} sẽ trả về {@code
479false}, vì thế bạn nên luôn gọi siêu lớp khi chưa được xử lý.)</p>
480</li>
481</ol>
482
483
484<h3 id="CAB">Sử dụng chế độ hành động theo ngữ cảnh</h3>
485
486<p>Chế độ hành động theo ngữ cảnh là một triển khai hệ thống {@link android.view.ActionMode}
487tập trung vào tương tác người dùng hướng tới việc thực hiện các hành động theo ngữ cảnh. Khi một
488người dùng kích hoạt chế độ này bằng cách chọn một mục, một <em>thanh hành động ngữ cảnh</em> sẽ xuất hiện bên trên
489màn hình để trình bày các hành động mà người dùng có thể thực hiện trên (các) mục đang được chọn. Trong khi
490chế độ này được kích hoạt, người dùng có thể chọn nhiều mục (nếu bạn cho phép), bỏ chọn mục, và tiếp tục
491điều hướng trong hoạt động (miễn là bạn sẵn lòng cho phép). Chế độ hành động bị vô hiệu hóa
492và thanh hành động ngữ cảnh biến mất khi người dùng bỏ chọn tất cả các mục, nhấn nút QUAY LẠI,
493hoặc chọn hành động <em>Xong</em> ở phía bên trái của thanh.</p>
494
495<p class="note"><strong>Lưu ý:</strong> Thanh hành động ngữ cảnh không nhất thiết
496phải được liên kết với <a href="{@docRoot}guide/topics/ui/actionbar.html">thanh hành động</a>. Chúng vận hành
497độc lập, mặc dù thanh hành động ngữ cảnh đè lên vị trí của thanh hành động
498về mặt hiển thị.</p>
499
500<p>Nếu bạn đang phát triển cho phiên bản Android 3.0 (API mức 11) hoặc cao hơn, bạn
501nên sử dụng chế độ hành động theo ngữ cảnh để trình bày các hành động ngữ cảnh, thay vì sử dụng <a href="#FloatingContextMenu">menu ngữ cảnh nổi</a>.</p>
502
503<p>Đối với các dạng xem cung cấp hành động ngữ cảnh, bạn nên thường xuyên gọi ra chế độ hành động theo ngữ cảnh
504khi xảy ra một trong hai sự kiện sau (hoặc cả hai):</p>
505<ul>
506  <li>Người dùng thực hiện nhấp giữ trên dạng xem.</li>
507  <li>Người dùng chọn một hộp kiểm hoặc một thành phần UI tương tự trong dạng xem.</li>
508</ul>
509
510<p>Cách ứng dụng của bạn gọi ra chế độ hành động theo ngữ cảnh và định nghĩa hành vi cho từng
511hành động phụ thuộc vào thiết kế của bạn. Cơ bản có hai thiết kế:</p>
512<ul>
513  <li>Đối với các hành động ngữ cảnh trên các dạng xem riêng lẻ, tùy ý.</li>
514  <li>Đối với các hành động ngữ cảnh hàng loạt trên các nhóm mục trong một {@link
515android.widget.ListView} hoặc {@link android.widget.GridView} (cho phép người dùng chọn nhiều
516mục và thực hiện một hành động trên tất cả).</li>
517</ul>
518
519<p>Các phần sau mô tả phần thiết lập cần thiết đối với từng kịch bản.</p>
520
521
522<h4 id="CABforViews">Kích hoạt chế độ hành động theo ngữ cảnh cho các dạng xem riêng lẻ</h4>
523
524<p>Nếu muốn gọi ra chế độ hành động theo ngữ cảnh chỉ khi người dùng chọn các dạng xem
525cụ thể, bạn nên:</p>
526<ol>
527  <li>Triển khai giao diện {@link android.view.ActionMode.Callback}. Trong các phương pháp gọi lại của giao diện, bạn
528có thể quy định các hành động cho thanh hành động ngữ cảnh, hồi đáp các sự kiện nhấp trên mục hành động, và
529xử lý các sự kiện vòng đời khác đối với chế độ hành động.</li>
530  <li>Gọi {@link android.app.Activity#startActionMode startActionMode()} khi bạn muốn hiển thị
531thanh (chẳng hạn như khi người dùng nhấp giữ dạng xem).</li>
532</ol>
533
534<p>Ví dụ:</p>
535
536<ol>
537  <li>Triển khai giao diện {@link android.view.ActionMode.Callback ActionMode.Callback}:
538<pre>
539private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
540
541    // Called when the action mode is created; startActionMode() was called
542    &#64;Override
543    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
544        // Inflate a menu resource providing context menu items
545        MenuInflater inflater = mode.getMenuInflater();
546        inflater.inflate(R.menu.context_menu, menu);
547        return true;
548    }
549
550    // Called each time the action mode is shown. Always called after onCreateActionMode, but
551    // may be called multiple times if the mode is invalidated.
552    &#64;Override
553    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
554        return false; // Return false if nothing is done
555    }
556
557    // Called when the user selects a contextual menu item
558    &#64;Override
559    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
560        switch (item.getItemId()) {
561            case R.id.menu_share:
562                shareCurrentItem();
563                mode.finish(); // Action picked, so close the CAB
564                return true;
565            default:
566                return false;
567        }
568    }
569
570    // Called when the user exits the action mode
571    &#64;Override
572    public void onDestroyActionMode(ActionMode mode) {
573        mActionMode = null;
574    }
575};
576</pre>
577
578<p>Lưu ý rằng những phương pháp gọi lại sự kiện này hầu như giống với các phương pháp gọi lại đối với <a href="#options-menu">menu tùy chọn</a>, khác ở chỗ từng phương pháp cũng chuyển đối tượng {@link
579android.view.ActionMode} được liên kết với sự kiện đó. Bạn có thể sử dụng các API {@link
580android.view.ActionMode} để thực hiện những thay đổi khác nhau với CAB, chẳng hạn như sửa đổi tiêu đề và
581phụ đề bằng {@link android.view.ActionMode#setTitle setTitle()} và {@link
582android.view.ActionMode#setSubtitle setSubtitle()} (hữu ích khi muốn cho biết có bao nhiêu mục
583được chọn).</p>
584
585<p>Cũng lưu ý rằng các bộ mẫu trên sẽ đặt biến {@code mActionMode} là rỗng khi
586chế độ hành động bị hủy. Ở bước tiếp theo, bạn sẽ thấy cách nó được khởi tạo và việc lưu
587biến thành viên trong hoạt động hoặc phân đoạn của bạn có thể hữu ích như thế nào.</p>
588</li>
589
590  <li>Gọi {@link android.app.Activity#startActionMode startActionMode()} để kích hoạt chế độ hành động theo ngữ cảnh
591khi phù hợp, chẳng hạn như để hồi đáp lại một sự kiện nhấp giữ trên một {@link
592android.view.View}:</p>
593
594<pre>
595someView.setOnLongClickListener(new View.OnLongClickListener() {
596    // Called when the user long-clicks on someView
597    public boolean onLongClick(View view) {
598        if (mActionMode != null) {
599            return false;
600        }
601
602        // Start the CAB using the ActionMode.Callback defined above
603        mActionMode = getActivity().startActionMode(mActionModeCallback);
604        view.setSelected(true);
605        return true;
606    }
607});
608</pre>
609
610<p>Khi bạn gọi {@link android.app.Activity#startActionMode startActionMode()}, hệ thống sẽ trả về
611{@link android.view.ActionMode} được tạo. Bằng cách lưu điều này trong một biến thành viên, bạn có thể
612thực hiện thay đổi thanh hành động theo ngữ cảnh để hồi đáp những sự kiện khác. Trong mẫu trên,
613{@link android.view.ActionMode} được sử dụng để đảm bảo rằng thực thể {@link android.view.ActionMode} không
614được tạo lại nếu nó đã hiện hoạt, bằng cách kiểm tra xem thành viên có rỗng không trước khi khởi động
615chế độ hành động.</p>
616</li>
617</ol>
618
619
620
621<h4 id="CABforListView">Kích hoạt hành động theo ngữ cảnh hàng loạt trong ListView hoặc GridView</h4>
622
623<p>Nếu bạn có một bộ sưu tập các mục trong một {@link android.widget.ListView} hoặc {@link
624android.widget.GridView} (hoặc một phần mở rộng khác của {@link android.widget.AbsListView}) và muốn
625cho phép người dùng thực hiện các hành động hàng loạt, bạn nên:</p>
626
627<ul>
628  <li>Triển khai giao diện {@link android.widget.AbsListView.MultiChoiceModeListener} và đặt nó
629cho nhóm dạng xem bằng {@link android.widget.AbsListView#setMultiChoiceModeListener
630setMultiChoiceModeListener()}. Trong các phương pháp gọi lại của trình nghe, bạn có thể quy định các hành động
631cho thanh hành động theo ngữ cảnh, hồi đáp các sự kiện nhấp trên các mục hành động, và xử lý các phương pháp gọi lại khác
632được kế thừa từ giao diện {@link android.view.ActionMode.Callback}.</li>
633
634  <li>Gọi {@link android.widget.AbsListView#setChoiceMode setChoiceMode()} bằng tham đối {@link
635android.widget.AbsListView#CHOICE_MODE_MULTIPLE_MODAL}.</li>
636</ul>
637
638<p>Ví dụ:</p>
639
640<pre>
641ListView listView = getListView();
642listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
643listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
644
645    &#64;Override
646    public void onItemCheckedStateChanged(ActionMode mode, int position,
647                                          long id, boolean checked) {
648        // Here you can do something when items are selected/de-selected,
649        // such as update the title in the CAB
650    }
651
652    &#64;Override
653    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
654        // Respond to clicks on the actions in the CAB
655        switch (item.getItemId()) {
656            case R.id.menu_delete:
657                deleteSelectedItems();
658                mode.finish(); // Action picked, so close the CAB
659                return true;
660            default:
661                return false;
662        }
663    }
664
665    &#64;Override
666    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
667        // Inflate the menu for the CAB
668        MenuInflater inflater = mode.getMenuInflater();
669        inflater.inflate(R.menu.context, menu);
670        return true;
671    }
672
673    &#64;Override
674    public void onDestroyActionMode(ActionMode mode) {
675        // Here you can make any necessary updates to the activity when
676        // the CAB is removed. By default, selected items are deselected/unchecked.
677    }
678
679    &#64;Override
680    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
681        // Here you can perform updates to the CAB due to
682        // an {@link android.view.ActionMode#invalidate} request
683        return false;
684    }
685});
686</pre>
687
688<p>Vậy là xong. Lúc này, khi người dùng chọn một mục bằng nhấp giữ, hệ thống sẽ gọi phương pháp {@link
689android.widget.AbsListView.MultiChoiceModeListener#onCreateActionMode onCreateActionMode()}
690và hiển thị thanh hành động theo ngữ cảnh với các hành động được quy định. Trong khi thanh hành động theo ngữ cảnh
691hiển thị, người dùng có thể chọn thêm mục.</p>
692
693<p>Trong một số trường hợp mà các hành động ngữ cảnh cung cấp các mục hành động chung, bạn có thể muốn
694thêm một hộp kiểm hoặc một phần tử UI tương tự để cho phép người dùng chọn các mục, vì
695họ có thể không phát hiện được hành vi nhấp giữ. Khi một người dùng chọn hộp kiểm, bạn
696có thể gọi ra chế độ hành động theo ngữ cảnh bằng cách thiết đặt mục danh sách tương ứng về trạng thái
697đã chọn bằng {@link android.widget.AbsListView#setItemChecked setItemChecked()}.</p>
698
699
700
701
702<h2 id="PopupMenu">Tạo một Menu Bật lên</h2>
703
704<div class="figure" style="width:220px">
705<img src="{@docRoot}images/ui/popupmenu.png" alt="" />
706<p><strong>Hình 4.</strong> Menu bật lên trong ứng dụng Gmail, được neo vào nút tràn
707ở trên cùng bên phải.</p>
708</div>
709
710<p>{@link android.widget.PopupMenu} là một menu mô thái được neo vào một {@link android.view.View}.
711Nó xuất hiện bên dưới dạng xem dấu neo nếu có khoảng trống, hoặc bên trên dạng xem nếu không. Nó có ích cho việc:</p>
712<ul>
713  <li>Cung cấp một menu kiểu tràn cho các hành động mà <em>liên quan tới</em> nội dung cụ thể (chẳng hạn như tiêu đề e-mail
714của Gmail như minh họa trong hình 4).
715    <p class="note"><strong>Lưu ý:</strong> Nó không giống như một menu ngữ cảnh, vốn thường
716áp dụng cho các hành động mà <em>ảnh hưởng</em> tới nội dung được chọn. Đối với những hành động ảnh hưởng tới nội dung
717được chọn, hãy sử dụng <a href="#CAB">chế độ hành động theo ngữ cảnh</a> hoặc <a href="#FloatingContextMenu">menu ngữ cảnh nổi</a>.</p></li>
718  <li>Cung cấp một phần thứ hai của câu lệnh (chẳng hạn như một nút được đánh dấu "Thêm"
719có chức năng tạo ra một menu bật lên với các tùy chọn "Thêm" khác nhau).</li>
720  <li>Cung cấp một danh sách thả xuống tương tự như {@link android.widget.Spinner}, nó không giữ lại một
721lựa chọn liên tục.</li>
722</ul>
723
724
725<p class="note"><strong>Lưu ý:</strong> {@link android.widget.PopupMenu} sẵn có với API
726mức 11 trở lên.</p>
727
728<p>Nếu bạn định nghĩa <a href="#xml">menu của mình trong XML</a>, sau đây là cách bạn có thể hiển thị menu bật lên:</p>
729<ol>
730  <li>Khởi tạo một {@link android.widget.PopupMenu} bằng hàm dựng của nó, có chức năng đưa
731ứng dụng hiện tại {@link android.content.Context} và {@link android.view.View} tới menu
732mà sẽ được neo.</li>
733  <li>Sử dụng {@link android.view.MenuInflater} để bung tài nguyên menu của bạn vào đối tượng {@link
734android.view.Menu} được trả về bởi {@link
735android.widget.PopupMenu#getMenu() PopupMenu.getMenu()}. Trên API mức 14 trở lên, bạn có thể sử dụng
736{@link android.widget.PopupMenu#inflate PopupMenu.inflate()} thay thế.</li>
737  <li>Gọi {@link android.widget.PopupMenu#show() PopupMenu.show()}.</li>
738</ol>
739
740<p>Ví dụ, sau đây là một nút với thuộc tính {@link android.R.attr#onClick android:onClick} có chức năng
741hiển thị một menu bật lên:</p>
742
743<pre>
744&lt;ImageButton
745    android:layout_width="wrap_content"
746    android:layout_height="wrap_content"
747    android:src="@drawable/ic_overflow_holo_dark"
748    android:contentDescription="@string/descr_overflow_button"
749    android:onClick="showPopup" />
750</pre>
751
752<p>Khi đó, hoạt động có thể hiển thị menu bật lên như sau:</p>
753
754<pre>
755public void showPopup(View v) {
756    PopupMenu popup = new PopupMenu(this, v);
757    MenuInflater inflater = popup.getMenuInflater();
758    inflater.inflate(R.menu.actions, popup.getMenu());
759    popup.show();
760}
761</pre>
762
763<p>Trong API mức 14 trở lên, bạn có thể kết hợp hai dòng có chức năng bung menu bằng {@link
764android.widget.PopupMenu#inflate PopupMenu.inflate()}.</p>
765
766<p>Menu bị bỏ qua khi người dùng chọn một mục hoặc chạm vào bên ngoài vùng
767menu. Bạn có thể lắng nghe báo hiệu sự kiện bỏ bằng cách sử dụng {@link
768android.widget.PopupMenu.OnDismissListener}.</p>
769
770<h3 id="PopupEvents">Xử lý sự kiện nhấp</h3>
771
772<p>Để thực hiện một
773hành động khi người dùng chọn một mục menu, bạn phải triển khai giao diện {@link
774android.widget.PopupMenu.OnMenuItemClickListener} và đăng ký nó với {@link
775android.widget.PopupMenu} của mình bằng cách gọi {@link android.widget.PopupMenu#setOnMenuItemClickListener
776setOnMenuItemclickListener()}. Khi người dùng chọn một mục, hệ thống sẽ gọi lệnh gọi lại {@link
777android.widget.PopupMenu.OnMenuItemClickListener#onMenuItemClick onMenuItemClick()} trong
778giao diện của bạn.</p>
779
780<p>Ví dụ:</p>
781
782<pre>
783public void showMenu(View v) {
784    PopupMenu popup = new PopupMenu(this, v);
785
786    // This activity implements OnMenuItemClickListener
787    popup.setOnMenuItemClickListener(this);
788    popup.inflate(R.menu.actions);
789    popup.show();
790}
791
792&#64;Override
793public boolean onMenuItemClick(MenuItem item) {
794    switch (item.getItemId()) {
795        case R.id.archive:
796            archive(item);
797            return true;
798        case R.id.delete:
799            delete(item);
800            return true;
801        default:
802            return false;
803    }
804}
805</pre>
806
807
808<h2 id="groups">Tạo Nhóm Menu</h2>
809
810<p>Nhóm menu là một tập hợp các mục menu chia sẻ những đặc điểm nhất định. Với một nhóm, bạn có thể
811:</p>
812<ul>
813  <li>Hiển thị hoặc ẩn tất cả các mục bằng {@link android.view.Menu#setGroupVisible(int,boolean)
814setGroupVisible()}</li>
815  <li>Kích hoạt hoặc vô hiệu hóa tất cả các mục bằng {@link android.view.Menu#setGroupEnabled(int,boolean)
816setGroupEnabled()}</li>
817  <li>Quy định xem tất cả các mục có thể chọn hay không bằng {@link
818android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()}</li>
819</ul>
820
821<p>Bạn có thể tạo một nhóm bằng cách lồng các phần tử {@code &lt;item&gt;} bên trong một phần tử {@code &lt;group&gt;}
822vào tài nguyên menu của bạn hoặc bằng cách quy định một ID nhóm bằng phương pháp {@link
823android.view.Menu#add(int,int,int,int) add()}.</p>
824
825<p>Sau đây là một ví dụ về tài nguyên menu bao gồm một nhóm:</p>
826
827<pre>
828&lt;?xml version="1.0" encoding="utf-8"?&gt;
829&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
830    &lt;item android:id="@+id/menu_save"
831          android:icon="@drawable/menu_save"
832          android:title="@string/menu_save" /&gt;
833    &lt;!-- menu group --&gt;
834    &lt;group android:id="@+id/group_delete"&gt;
835        &lt;item android:id="@+id/menu_archive"
836              android:title="@string/menu_archive" /&gt;
837        &lt;item android:id="@+id/menu_delete"
838              android:title="@string/menu_delete" /&gt;
839    &lt;/group&gt;
840&lt;/menu&gt;
841</pre>
842
843<p>Các mục nằm trong nhóm xuất hiện ở cùng cấp như mục đầu tiên&mdash;tất cả ba mục
844trong menu đều là các mục đồng cấp. Tuy nhiên, bạn có thể sửa đổi các đặc điểm của hai
845mục trong nhóm bằng cách tham chiếu ID nhóm và sử dụng các phương pháp được liệt kê bên trên. Hệ thống cũng sẽ
846không bao giờ tách riêng các mục đã ghép nhóm. Ví dụ, nếu bạn khai báo {@code
847android:showAsAction="ifRoom"} cho từng mục, chúng sẽ hoặc đều xuất hiện trong thanh hành động
848hoặc đều xuất hiện trong phần tràn hành động.</p>
849
850
851<h3 id="checkable">Sử dụng mục menu có thể chọn</h3>
852
853<div class="figure" style="width:200px">
854  <img src="{@docRoot}images/radio_buttons.png" height="333" alt="" />
855  <p class="img-caption"><strong>Hình 5.</strong> Ảnh chụp màn hình một menu con với các mục
856có thể chọn.</p>
857</div>
858
859<p>Một mục có thể có ích như một giao diện để bật và tắt các tùy chọn, bằng cách sử dụng một hộp kiểm cho
860các tùy chọn độc lập, hoặc nút chọn một cho các nhóm
861tùy chọn loại trừ lẫn nhau. Hình 5 minh họa một menu con với các mục có thể chọn bằng các nút
862 chọn một.</p>
863
864<p class="note"><strong>Lưu ý:</strong> Các mục menu trong Menu Biểu tượng (từ menu tùy chọn) không thể
865hiển thị một hộp kiểm hay nút chọn một. Nếu bạn chọn đặt các mục trong Menu Biểu tượng là có thể chọn,
866bạn phải chỉ định trạng thái được chọn bằng cách tráo đổi biểu tượng và/hoặc văn bản
867mỗi lần trạng thái thay đổi một cách thủ công.</p>
868
869<p>Bạn có thể định nghĩa hành vi có thể chọn cho các mục menu riêng lẻ bằng cách sử dụng thuộc tính {@code
870android:checkable} trong phần tử {@code &lt;item&gt;}, hoặc cho toàn bộ nhóm với
871thuộc tính {@code android:checkableBehavior} trong phần tử {@code &lt;group&gt;}. Ví
872dụ, tất cả các mục trong nhóm menu này có thể chọn bằng một nút chọn một:</p>
873
874<pre>
875&lt;?xml version="1.0" encoding="utf-8"?&gt;
876&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
877    &lt;group android:checkableBehavior="single"&gt;
878        &lt;item android:id="@+id/red"
879              android:title="@string/red" /&gt;
880        &lt;item android:id="@+id/blue"
881              android:title="@string/blue" /&gt;
882    &lt;/group&gt;
883&lt;/menu&gt;
884</pre>
885
886<p>Thuộc tính {@code android:checkableBehavior} chấp nhận hoặc:
887<dl>
888  <dt>{@code single}</dt>
889    <dd>Chỉ chọn được một mục từ nhóm (nút chọn một)</dd>
890  <dt>{@code all}</dt>
891    <dd>Có thể chọn được tất cả các mục (hộp kiểm)</dd>
892  <dt>{@code none}</dt>
893    <dd>Không chọn được mục nào</dd>
894</dl>
895
896<p>Bạn có thể áp dụng một trạng thái được chọn mặc định cho một mục bằng cách sử dụng thuộc tính {@code android:checked} trong
897phần tử {@code &lt;item&gt;} và thay đổi nó trong mã bằng phương pháp {@link
898android.view.MenuItem#setChecked(boolean) setChecked()}.</p>
899
900<p>Khi chọn một mục có thể chọn, hệ thống sẽ gọi phương pháp gọi lại mục được chọn tương ứng
901(chẳng hạn như {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}). Chính
902ở đây bạn phải đặt trạng thái của hộp kiểm, vì hộp kiểm hay nút chọn một đều không
903tự động thay đổi trạng thái của nó. Bạn có thể truy vấn trạng thái hiện tại của mục (như trước khi
904người dùng chọn) bằng {@link android.view.MenuItem#isChecked()} và sau đó đặt trạng thái được chọn bằng
905{@link android.view.MenuItem#setChecked(boolean) setChecked()}. Ví dụ:</p>
906
907<pre>
908&#64;Override
909public boolean onOptionsItemSelected(MenuItem item) {
910    switch (item.getItemId()) {
911        case R.id.vibrate:
912        case R.id.dont_vibrate:
913            if (item.isChecked()) item.setChecked(false);
914            else item.setChecked(true);
915            return true;
916        default:
917            return super.onOptionsItemSelected(item);
918    }
919}
920</pre>
921
922<p>Nếu bạn không đặt trạng thái được chọn bằng cách này, khi đó trạng thái hiển thị của mục (hộp kiểm hoặc
923nút chọn một) sẽ không
924thay đổi khi người dùng chọn nó. Khi bạn đặt trạng thái, hoạt động sẽ giữ nguyên trạng thái được chọn
925của mục đó để khi người dùng mở menu sau, trạng thái được chọn mà bạn đặt
926sẽ được hiển thị.</p>
927
928<p class="note"><strong>Lưu ý:</strong>
929Các mục menu có thể chọn được chỉ định sử dụng trên mỗi phiên và không được lưu sau khi
930ứng dụng bị hủy. Nếu bạn có các cài đặt ứng dụng mà bạn muốn lưu cho người dùng,
931bạn nên lưu trữ dữ liệu bằng cách sử dụng <a href="{@docRoot}guide/topics/data/data-storage.html#pref">Tùy chọn dùng chung</a>.</p>
932
933
934
935<h2 id="intents">Thêm Mục Menu dựa trên Ý định</h2>
936
937<p>Đôi khi bạn sẽ muốn một mục menu khởi chạy một hoạt động bằng cách sử dụng một {@link android.content.Intent}
938(dù đó là một hoạt động trong ứng dụng của bạn hay một ứng dụng khác). Khi bạn biết ý định mà mình
939muốn sử dụng và có một mục menu cụ thể sẽ khởi tạo ý định, bạn có thể thực thi ý định
940bằng {@link android.app.Activity#startActivity(Intent) startActivity()} trong phương pháp gọi lại
941phù hợp theo mục được chọn (chẳng hạn như lệnh gọi lại {@link
942android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}).</p>
943
944<p>Tuy nhiên, nếu bạn không chắc chắn rằng thiết bị của người dùng
945chứa một ứng dụng xử lý ý định đó thì việc thêm một mục menu gọi nó ra có thể dẫn đến
946mục menu không hoạt động, do ý định có thể không phân giải thành một
947hoạt động. Để giải quyết điều này, Android cho phép bạn linh hoạt thêm các mục menu vào menu của mình
948khi Android tìm các hoạt động trên thiết bị để xử lý ý định của bạn.</p>
949
950<p>Để thêm các mục menu dựa trên các hoạt động sẵn có mà chấp nhận ý định:</p>
951<ol>
952  <li>Định nghĩa một
953ý định bằng thể loại {@link android.content.Intent#CATEGORY_ALTERNATIVE} và/hoặc
954{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE}, cộng với bất kỳ yêu cầu nào khác.</li>
955  <li>Gọi {@link
956android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
957Menu.addIntentOptions()}. Sau đó, Android tìm kiếm bất kỳ ứng dụng nào có thể thực hiện ý định
958và thêm chúng vào menu của bạn.</li>
959</ol>
960
961<p>Nếu không có ứng dụng được cài đặt
962mà thỏa mãn ý định thì không có mục menu nào được thêm vào.</p>
963
964<p class="note"><strong>Lưu ý:</strong>
965{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} được sử dụng để xử lý
966phần tử đang được chọn trên màn hình. Vì vậy, nó chỉ nên được sử dụng khi tạo một Menu trong {@link
967android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo)
968onCreateContextMenu()}.</p>
969
970<p>Ví dụ:</p>
971
972<pre>
973&#64;Override
974public boolean onCreateOptionsMenu(Menu menu){
975    super.onCreateOptionsMenu(menu);
976
977    // Create an Intent that describes the requirements to fulfill, to be included
978    // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
979    Intent intent = new Intent(null, dataUri);
980    intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
981
982    // Search and populate the menu with acceptable offering applications.
983    menu.addIntentOptions(
984         R.id.intent_group,  // Menu group to which new items will be added
985         0,      // Unique item ID (none)
986         0,      // Order for the items (none)
987         this.getComponentName(),   // The current activity name
988         null,   // Specific items to place first (none)
989         intent, // Intent created above that describes our requirements
990         0,      // Additional flags to control items (none)
991         null);  // Array of MenuItems that correlate to specific items (none)
992
993    return true;
994}</pre>
995
996<p>Đối với mỗi hoạt động được tìm thấy mà cung cấp một bộ lọc ý định khớp với ý định được định nghĩa, một mục menu
997được thêm, bằng cách sử dụng giá trị trong <code>android:label</code> của bộ lọc ý định làm
998tiêu đề của mục menu và biểu tượng của ứng dụng làm biểu tượng của mục menu. Phương pháp
999{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
1000addIntentOptions()} trả về số mục menu được thêm.</p>
1001
1002<p class="note"><strong>Lưu ý:</strong> Khi bạn gọi {@link
1003android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
1004addIntentOptions()}, nó sẽ khống chế bất kỳ và tất cả các mục menu theo nhóm menu được quy định trong tham đối
1005đầu tiên.</p>
1006
1007
1008<h3 id="AllowingToAdd">Cho phép hoạt động của bạn được thêm vào các menu khác</h3>
1009
1010<p>Bạn cũng có thể cung cấp các dịch vụ của hoạt động của mình cho các ứng dụng khác, vì vậy ứng dụng của bạn
1011có thể nằm trong menu của các ứng dụng khác (đảo ngược vai trò nêu trên).</p>
1012
1013<p>Để được nằm trong menu của ứng dụng khác, bạn cần định nghĩa một bộ lọc
1014ý định như bình thường, nhưng đảm bảo thêm các giá trị {@link android.content.Intent#CATEGORY_ALTERNATIVE}
1015và/hoặc {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} cho thể loại
1016bộ lọc ý định. Ví dụ:</p>
1017<pre>
1018&lt;intent-filter label="&#64;string/resize_image">
1019    ...
1020    &lt;category android:name="android.intent.category.ALTERNATIVE" />
1021    &lt;category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
1022    ...
1023&lt;/intent-filter>
1024</pre>
1025
1026<p>Tìm hiểu thêm về việc ghi các bộ lọc ý định trong tài liệu
1027<a href="/guide/components/intents-filters.html">Ý định và Bộ lọc Ý định</a>.</p>
1028
1029<p>Để tham khảo một ứng dụng mẫu sử dụng kỹ thuật này, hãy xem mã mẫu
1030<a href="{@docRoot}resources/samples/NotePad/src/com/example/android/notepad/NoteEditor.html">Note
1031Pad</a>.</p>
1032