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—đó 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><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><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><item></code> và <code><group></code>.</dd> 134 135 <dt><code><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><menu></code> được lồng nhau để tạo một menu con.</dd> 138 139 <dt><code><group></code></dt> 140 <dd>Một bộ chứa tùy chọn, vô hình cho các phần tử {@code <item>}. 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<?xml version="1.0" encoding="utf-8"?> 149<menu xmlns:android="http://schemas.android.com/apk/res/android"> 150 <item android:id="@+id/new_game" 151 android:icon="@drawable/ic_new_game" 152 android:title="@string/new_game" 153 android:showAsAction="ifRoom"/> 154 <item android:id="@+id/help" 155 android:icon="@drawable/ic_help" 156 android:title="@string/help" /> 157</menu> 158</pre> 159 160<p>Phần tử <code><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 <menu>} 179làm con của {@code <item>}. 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<?xml version="1.0" encoding="utf-8"?> 185<menu xmlns:android="http://schemas.android.com/apk/res/android"> 186 <item android:id="@+id/file" 187 android:title="@string/file" > 188 <!-- "file" submenu --> 189 <menu> 190 <item android:id="@+id/create_new" 191 android:title="@string/create_new" /> 192 <item android:id="@+id/open" 193 android:title="@string/open" /> 194 </menu> 195 </item> 196</menu> 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 <item>} 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 <item>} 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@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@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—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@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@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 @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 @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 @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 @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 @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 @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 @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 @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 @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<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@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 <item>} bên trong một phần tử {@code <group>} 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<?xml version="1.0" encoding="utf-8"?> 829<menu xmlns:android="http://schemas.android.com/apk/res/android"> 830 <item android:id="@+id/menu_save" 831 android:icon="@drawable/menu_save" 832 android:title="@string/menu_save" /> 833 <!-- menu group --> 834 <group android:id="@+id/group_delete"> 835 <item android:id="@+id/menu_archive" 836 android:title="@string/menu_archive" /> 837 <item android:id="@+id/menu_delete" 838 android:title="@string/menu_delete" /> 839 </group> 840</menu> 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—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 <item>}, hoặc cho toàn bộ nhóm với 871thuộc tính {@code android:checkableBehavior} trong phần tử {@code <group>}. 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<?xml version="1.0" encoding="utf-8"?> 876<menu xmlns:android="http://schemas.android.com/apk/res/android"> 877 <group android:checkableBehavior="single"> 878 <item android:id="@+id/red" 879 android:title="@string/red" /> 880 <item android:id="@+id/blue" 881 android:title="@string/blue" /> 882 </group> 883</menu> 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 <item>} 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@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@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<intent-filter label="@string/resize_image"> 1019 ... 1020 <category android:name="android.intent.category.ALTERNATIVE" /> 1021 <category android:name="android.intent.category.SELECTED_ALTERNATIVE" /> 1022 ... 1023</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