1page.title=Hộp thoại 2page.tags=alertdialog,dialogfragment 3 4@jd:body 5 6 7 8<div id="qv-wrapper"> 9 <div id="qv"> 10 <h2>Trong tài liệu này</h2> 11<ol> 12 <li><a href="#DialogFragment">Tạo một Phân đoạn Hộp thoại</a></li> 13 <li><a href="#AlertDialog">Xây dựng một Hộp thoại Cảnh báo</a> 14 <ol> 15 <li><a href="#AddingButtons">Thêm nút</a></li> 16 <li><a href="#AddingAList">Thêm một danh sách</a></li> 17 <li><a href="#CustomLayout">Tạo một Bố trí Tùy chỉnh</a></li> 18 </ol> 19 </li> 20 <li><a href="#PassingEvents">Chuyển Sự kiện lại Máy chủ của Hộp thoại</a></li> 21 <li><a href="#ShowingADialog">Hiển thị một Hộp thoại</a></li> 22 <li><a href="#FullscreenDialog">Hiển thị một Hộp thoại Toàn màn hình hoặc dạng một Phân đoạn Nhúng</a> 23 <ol> 24 <li><a href="#ActivityAsDialog">Hiển thị một hoạt động dưới dạng một hộp thoại trên màn hình lớn</a></li> 25 </ol> 26 </li> 27 <li><a href="#DismissingADialog">Bỏ một Hộp thoại</a></li> 28</ol> 29 30 <h2>Lớp khóa</h2> 31 <ol> 32 <li>{@link android.app.DialogFragment}</li> 33 <li>{@link android.app.AlertDialog}</li> 34 </ol> 35 36 <h2>Xem thêm</h2> 37 <ol> 38 <li><a href="{@docRoot}design/building-blocks/dialogs.html">Hướng dẫn thiết kế hộp thoại</a></li> 39 <li><a href="{@docRoot}guide/topics/ui/controls/pickers.html">Bộ chọn</a> (Hộp thoại Ngày/Giờ)</li> 40 </ol> 41 </div> 42</div> 43 44<p>Hộp thoại là một cửa sổ nhỏ có chức năng nhắc người dùng 45đưa ra một quyết định hoặc nhập thông tin bổ sung. Hộp thoại không lấp kín màn hình và 46thường được sử dụng cho các sự kiện mô thái yêu cầu người dùng phải thực hiện một hành động trước khi có thể đi tiếp.</p> 47 48<div class="note design"> 49<p><strong>Thiết kế Hộp thoại</strong></p> 50 <p>Để biết thông tin về cách thiết kế hộp thoại của bạn, bao gồm các đề xuất 51 về ngôn ngữ, hãy đọc hướng dẫn thiết kế <a href="{@docRoot}design/building-blocks/dialogs.html">Hộp thoại</a>.</p> 52</div> 53 54<img src="{@docRoot}images/ui/dialogs.png" /> 55 56<p>Lớp {@link android.app.Dialog} là lớp cơ sở cho hộp thoại, nhưng bạn 57nên tránh khởi tạo {@link android.app.Dialog} một cách trực tiếp. 58Thay vào đó, hãy sử dụng một trong các lớp con sau:</p> 59<dl> 60 <dt>{@link android.app.AlertDialog}</dt> 61 <dd>Hộp thoại có thể hiển thị một tiêu đề, tối đa ba nút, một danh sách 62 các mục có thể chọn, hoặc một bố trí tùy chỉnh.</dd> 63 <dt>{@link android.app.DatePickerDialog} hoặc {@link android.app.TimePickerDialog}</dt> 64 <dd>Hộp thoại với một UI được xác định trước, cho phép người dùng chọn ngày hoặc giờ.</dd> 65</dl> 66 67<div class="sidebox"> 68<h2>Tránh ProgressDialog</h2> 69<p>Android có một lớp hộp thoại khác gọi là 70{@link android.app.ProgressDialog}, nó hiển thị một hộp thoại với một thanh tiến độ. Tuy nhiên, nếu bạn 71cần chỉ báo tiến độ tải hoặc chưa xác định, thay vào đó, bạn nên tuân theo hướng dẫn 72thiết kế dành cho <a href="{@docRoot}design/building-blocks/progress.html">Tiến độ & 73Hoạt động</a> và sử dụng một {@link android.widget.ProgressBar} trong bố trí của mình.</p> 74</div> 75 76<p>Những lớp này định nghĩa kiểu và cấu trúc cho hộp thoại của bạn, nhưng bạn nên 77sử dụng một {@link android.support.v4.app.DialogFragment} làm bộ chứa cho hộp thoại của mình. 78Lớp {@link android.support.v4.app.DialogFragment} sẽ cung cấp tất cả điều khiển mà 79bạn cần để tạo hộp thoại của mình và quản lý diện mạo của hộp thoại, thay vì gọi ra các phương pháp 80trên đối tượng {@link android.app.Dialog}.</p> 81 82<p>Việc sử dụng {@link android.support.v4.app.DialogFragment} để quản lý hộp thoại 83sẽ đảm bảo rằng nó xử lý đúng các sự kiện vòng đời 84chẳng hạn như khi người dùng nhấn nút <em>Quay lại</em> hoặc xoay màn hình. Lớp {@link 85android.support.v4.app.DialogFragment} cũng cho phép bạn sử dụng lại UI của hộp thoại như một 86thành phần có thể nhúng trong một UI rộng hơn, giống như một {@link 87android.support.v4.app.Fragment} truyền thống (chẳng hạn như khi bạn muốn UI hộp thoại xuất hiện khác đi 88trên các màn hình lớn và nhỏ).</p> 89 90<p>Các phần sau trong hướng dẫn này mô tả cách sử dụng {@link 91android.support.v4.app.DialogFragment} kết hợp với một đối tượng {@link android.app.AlertDialog} 92. Nếu muốn tạo một bộ chọn ngày hoặc giờ, thay vào đó, bạn nên đọc hướng dẫn 93<a href="{@docRoot}guide/topics/ui/controls/pickers.html">Bộ chọn</a>.</p> 94 95<p class="note"><strong>Lưu ý:</strong> 96Vì lớp {@link android.app.DialogFragment} ban đầu được bổ sung cùng với 97Android 3.0 (API mức 11), tài liệu này mô tả cách sử dụng lớp {@link 98android.support.v4.app.DialogFragment} được cung cấp kèm <a href="{@docRoot}tools/support-library/index.html">Thư viện Hỗ trợ</a>. Bằng cách thêm thư viện này 99vào ứng dụng của mình, bạn có thể sử dụng {@link android.support.v4.app.DialogFragment} và nhiều loại 100API khác trên các thiết bị chạy Android 1.6 hoặc cao hơn. Nếu phiên bản tối thiểu mà ứng dụng của bạn hỗ trợ 101là API mức 11 hoặc cao hơn, khi đó bạn có thể sử dụng phiên bản khuôn khổ của {@link 102android.app.DialogFragment}, nhưng hãy chú ý rằng các liên kết trong tài liệu này dành cho các API 103thư viện hỗ trợ. Khi sử dụng thư viện hỗ trợ, 104hãy nhớ rằng bạn nhập lớp <code>android.support.v4.app.DialogFragment</code> 105chứ <em>không phải</em> <code>android.app.DialogFragment</code>.</p> 106 107 108<h2 id="DialogFragment">Tạo một Phân đoạn Hộp thoại</h2> 109 110<p>Bạn có thể hoàn thành nhiều loại thiết kế hộp thoại—bao gồm 111bố trí tùy chỉnh và những bố trí được mô tả trong hướng dẫn thiết kế <a href="{@docRoot}design/building-blocks/dialogs.html">Hộp thoại</a> 112—bằng cách mở rộng 113{@link android.support.v4.app.DialogFragment} và tạo một {@link android.app.AlertDialog} 114trong phương pháp gọi lại {@link android.support.v4.app.DialogFragment#onCreateDialog 115onCreateDialog()}.</p> 116 117<p>Ví dụ, sau đây là một {@link android.app.AlertDialog} cơ bản được quản lý bên trong 118một {@link android.support.v4.app.DialogFragment}:</p> 119 120<pre> 121public class FireMissilesDialogFragment extends DialogFragment { 122 @Override 123 public Dialog onCreateDialog(Bundle savedInstanceState) { 124 // Use the Builder class for convenient dialog construction 125 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 126 builder.setMessage(R.string.dialog_fire_missiles) 127 .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { 128 public void onClick(DialogInterface dialog, int id) { 129 // FIRE ZE MISSILES! 130 } 131 }) 132 .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 133 public void onClick(DialogInterface dialog, int id) { 134 // User cancelled the dialog 135 } 136 }); 137 // Create the AlertDialog object and return it 138 return builder.create(); 139 } 140} 141</pre> 142 143<div class="figure" style="width:290px;margin:0 0 0 20px"> 144<img src="{@docRoot}images/ui/dialog_buttons.png" alt="" /> 145<p class="img-caption"><strong>Hình 1.</strong> 146Hộp thoại với một thông báo và hai nút hành động.</p> 147</div> 148 149<p>Lúc này, khi bạn tạo một thực thể thuộc lớp này và gọi {@link 150android.support.v4.app.DialogFragment#show show()} trên đối tượng đó, hộp thoại sẽ xuất hiện 151như minh họa trong hình 1.</p> 152 153<p>Phần tiếp theo mô tả thêm về việc sử dụng các API {@link android.app.AlertDialog.Builder} 154để tạo hộp thoại.</p> 155 156<p>Tùy vào độ phức tạp của hộp thoại của bạn, bạn có thể triển khai nhiều loại phương pháp gọi lại khác 157trong {@link android.support.v4.app.DialogFragment}, bao gồm tất cả 158<a href="{@docRoot}guide/components/fragments.html#Lifecycle">phương pháp vòng đời phân đoạn</a> cơ bản. 159 160 161 162 163 164<h2 id="AlertDialog">Xây dựng một Hộp thoại Cảnh báo</h2> 165 166 167<p>Lớp {@link android.app.AlertDialog} cho phép bạn xây dựng nhiều loại thiết kế hộp thoại và 168thường là lớp hộp thoại duy nhất mà bạn sẽ cần. 169Như được minh họa trong hình 2, có ba vùng trên một hộp thoại cảnh báo:</p> 170 171<div class="figure" style="width:311px;margin-top:0"> 172<img src="{@docRoot}images/ui/dialogs_regions.png" alt="" style="margin-bottom:0" /> 173<p class="img-caption"><strong>Hình 2.</strong> Bố trí của một hộp thoại.</p> 174</div> 175 176<ol> 177<li><b>Tiêu đề</b> 178 <p>Tiêu đề không bắt buộc và chỉ nên được sử dụng khi vùng nội dung 179 bị chiếm bởi một thông báo chi tiết, một danh sách, hay một bố trí tùy chỉnh. Nếu bạn cần nêu 180 một thông báo hoặc câu hỏi đơn giản (chẳng hạn như hộp thoại trong hình 1), bạn không cần tiêu đề.</li> 181<li><b>Vùng nội dung</b> 182 <p>Vùng này có thể hiển thị một thông báo, danh sách, hay bố trí tùy chỉnh khác.</p></li> 183<li><b>Nút hành động</b> 184 <p>Sẽ không có quá ba nút hành động trong một hộp thoại.</p></li> 185</ol> 186 187<p>Lớp {@link android.app.AlertDialog.Builder} 188cung cấp các API cho phép bạn tạo một {@link android.app.AlertDialog} 189với những kiểu nội dung này, bao gồm một bố trí tùy chỉnh.</p> 190 191<p>Để xây dựng một {@link android.app.AlertDialog}:</p> 192 193<pre> 194<b>// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor</b> 195AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 196 197<b>// 2. Chain together various setter methods to set the dialog characteristics</b> 198builder.setMessage(R.string.dialog_message) 199 .setTitle(R.string.dialog_title); 200 201<b>// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}</b> 202AlertDialog dialog = builder.create(); 203</pre> 204 205<p>Các chủ đề sau cho biết cách định nghĩa các thuộc tính hộp thoại khác nhau bằng cách 206sử dụng lớp {@link android.app.AlertDialog.Builder}.</p> 207 208 209 210 211<h3 id="AddingButtons">Thêm nút</h3> 212 213<p>Để thêm các nút hành động như trong hình 2, 214hãy gọi các phương pháp {@link android.app.AlertDialog.Builder#setPositiveButton setPositiveButton()} và 215{@link android.app.AlertDialog.Builder#setNegativeButton setNegativeButton()}:</p> 216 217<pre style="clear:right"> 218AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 219// Add the buttons 220builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 221 public void onClick(DialogInterface dialog, int id) { 222 // User clicked OK button 223 } 224 }); 225builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 226 public void onClick(DialogInterface dialog, int id) { 227 // User cancelled the dialog 228 } 229 }); 230// Set other dialog properties 231... 232 233// Create the AlertDialog 234AlertDialog dialog = builder.create(); 235</pre> 236 237<p>Các phương pháp <code>set...Button()</code> yêu cầu một tiêu đề cho nút (được cung cấp 238bởi một <a href="{@docRoot}guide/topics/resources/string-resource.html">tài nguyên xâu</a>) và một 239{@link android.content.DialogInterface.OnClickListener} có chức năng định nghĩa hành động sẽ tiến hành 240khi người dùng nhấn nút.</p> 241 242<p>Có ba nút hành động khác nhau mà bạn có thể thêm:</p> 243<dl> 244 <dt>Tích cực</dt> 245 <dd>Bạn nên sử dụng nút này để chấp nhận và tiếp tục với hành động (hành động "OK").</dd> 246 <dt>Tiêu cực</dt> 247 <dd>Bạn nên sử dụng nút này để hủy bỏ hành động.</dd> 248 <dt>Trung lập</dt> 249 <dd>Bạn nên sử dụng nút này khi người dùng có thể không muốn tiếp tục với hành động, 250 nhưng không hẳn muốn hủy bỏ. Nó nằm ở giữa nút 251 tích cực và tiêu cực. Ví dụ, hành động có thể là "Nhắc tôi sau."</dd> 252</dl> 253 254<p>Bạn chỉ có thể thêm một nút mỗi loại vào một {@link 255android.app.AlertDialog}. Nghĩa là, bạn không thể có nhiều hơn một nút "tích cực".</p> 256 257 258 259<div class="figure" style="width:290px;margin:0 0 0 40px"> 260<img src="{@docRoot}images/ui/dialog_list.png" alt="" /> 261<p class="img-caption"><strong>Hình 3.</strong> 262Hộp thoại có tiêu đề và danh sách.</p> 263</div> 264 265<h3 id="AddingAList">Thêm một danh sách</h3> 266 267<p>Có ba loại danh sách có sẵn với các API {@link android.app.AlertDialog}:</p> 268<ul> 269<li>Danh sách một lựa chọn truyền thống</li> 270<li>Danh sách một lựa chọn cố định (nút chọn một)</li> 271<li>Danh sách nhiều lựa chọn cố định (hộp kiểm)</li> 272</ul> 273 274<p>Để tạo danh sách một lựa chọn như danh sách trong hình 3, 275hãy sử dụng phương pháp {@link android.app.AlertDialog.Builder#setItems setItems()}:</p> 276 277<pre style="clear:right"> 278@Override 279public Dialog onCreateDialog(Bundle savedInstanceState) { 280 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 281 builder.setTitle(R.string.pick_color) 282 .setItems(R.array.colors_array, new DialogInterface.OnClickListener() { 283 public void onClick(DialogInterface dialog, int which) { 284 // The 'which' argument contains the index position 285 // of the selected item 286 } 287 }); 288 return builder.create(); 289} 290</pre> 291 292<p>Vì danh sách xuất hiện trong vùng nội dung của hộp thoại, 293hộp thoại không thể hiển thị cả thông báo và danh sách và bạn nên đặt một tiêu đề cho hộp thoại 294bằng {@link android.app.AlertDialog.Builder#setTitle setTitle()}. 295Để chỉ định các mục cho danh sách, hãy gọi {@link 296android.app.AlertDialog.Builder#setItems setItems()}, chuyển một mảng. 297Hoặc, bạn có thể chỉ định một danh sách bằng cách sử dụng {@link 298android.app.AlertDialog.Builder#setAdapter setAdapter()}. Điều này cho phép bạn hỗ trợ danh sách 299bằng dữ liệu động (chẳng hạn như từ một cơ sở dữ liệu) bằng cách sử dụng {@link android.widget.ListAdapter}.</p> 300 301<p>Nếu bạn chọn hỗ trợ danh sách của mình bằng một {@link android.widget.ListAdapter}, 302hãy luôn sử dụng {@link android.support.v4.content.Loader} sao cho nội dung tải 303không đồng bộ. Điều này được mô tả thêm trong hướng dẫn 304<a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Xây dựng Bố trí 305bằng một Trình điều hợp</a> và <a href="{@docRoot}guide/components/loaders.html">Trình tải</a> 306.</p> 307 308<p class="note"><strong>Lưu ý:</strong> Theo mặc định, chạm vào một mục danh sách sẽ bỏ hộp thoại, 309trừ khi bạn đang sử dụng một trong các danh sách lựa chọn cố định sau.</p> 310 311<div class="figure" style="width:290px;margin:-30px 0 0 40px"> 312<img src="{@docRoot}images/ui/dialog_checkboxes.png" /> 313<p class="img-caption"><strong>Hình 4.</strong> 314Danh sách nhiều mục lựa chọn.</p> 315</div> 316 317 318<h4 id="Checkboxes">Thêm một danh sách nhiều lựa chọn hoặc một lựa chọn cố định</h4> 319 320<p>Để thêm một danh sách nhiều lựa chọn (hộp kiểm) hoặc 321một lựa chọn (nút chọn một), hãy sử dụng các phương pháp 322{@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String, 323DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} hoặc 324{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) 325setSingleChoiceItems()} tương ứng.</p> 326 327<p>Ví dụ, sau đây là cách bạn có thể tạo một danh sách nhiều lựa chọn như 328danh sách được minh họa trong hình 4 giúp lưu các mục 329được chọn trong một {@link java.util.ArrayList}:</p> 330 331<pre style="clear:right"> 332@Override 333public Dialog onCreateDialog(Bundle savedInstanceState) { 334 mSelectedItems = new ArrayList(); // Where we track the selected items 335 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 336 // Set the dialog title 337 builder.setTitle(R.string.pick_toppings) 338 // Specify the list array, the items to be selected by default (null for none), 339 // and the listener through which to receive callbacks when items are selected 340 .setMultiChoiceItems(R.array.toppings, null, 341 new DialogInterface.OnMultiChoiceClickListener() { 342 @Override 343 public void onClick(DialogInterface dialog, int which, 344 boolean isChecked) { 345 if (isChecked) { 346 // If the user checked the item, add it to the selected items 347 mSelectedItems.add(which); 348 } else if (mSelectedItems.contains(which)) { 349 // Else, if the item is already in the array, remove it 350 mSelectedItems.remove(Integer.valueOf(which)); 351 } 352 } 353 }) 354 // Set the action buttons 355 .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 356 @Override 357 public void onClick(DialogInterface dialog, int id) { 358 // User clicked OK, so save the mSelectedItems results somewhere 359 // or return them to the component that opened the dialog 360 ... 361 } 362 }) 363 .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 364 @Override 365 public void onClick(DialogInterface dialog, int id) { 366 ... 367 } 368 }); 369 370 return builder.create(); 371} 372</pre> 373 374<p>Mặc dù cả danh sách truyền thống và danh sách có nút chọn một 375đều cung cấp hành động "một lựa chọn", bạn nên sử dụng {@link 376android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) 377setSingleChoiceItems()} nếu bạn muốn cố định lựa chọn của người dùng. 378Cụ thể, nếu việc mở hộp thoại lại sau này báo hiệu lựa chọn hiện tại của người dùng, khi đó 379bạn hãy tạo một danh sách với các nút chọn một.</p> 380 381 382 383 384 385<h3 id="CustomLayout">Tạo một Bố trí Tùy chỉnh</h3> 386 387<div class="figure" style="width:290px;margin:-30px 0 0 40px"> 388<img src="{@docRoot}images/ui/dialog_custom.png" alt="" /> 389<p class="img-caption"><strong>Hình 5.</strong> Một bố trí hộp thoại tùy chỉnh.</p> 390</div> 391 392<p>Nếu bạn muốn một bố trí tùy chỉnh trong một hộp thoại, hãy tạo một bố trí và thêm nó vào một 393{@link android.app.AlertDialog} bằng cách gọi {@link 394android.app.AlertDialog.Builder#setView setView()} trên đối tượng {@link 395android.app.AlertDialog.Builder} của bạn.</p> 396 397<p>Theo mặc định, bố trí tùy chỉnh sẽ lấp đầy cửa sổ hộp thoại, nhưng bạn vẫn có thể 398sử dụng các phương pháp {@link android.app.AlertDialog.Builder} để thêm nút và tiêu đề.</p> 399 400<p>Ví dụ, sau đây là tệp bố trí cho hộp thoại trong Hình 5:</p> 401 402<p style="clear:right" class="code-caption">res/layout/dialog_signin.xml</p> 403<pre> 404<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 405 android:orientation="vertical" 406 android:layout_width="wrap_content" 407 android:layout_height="wrap_content"> 408 <ImageView 409 android:src="@drawable/header_logo" 410 android:layout_width="match_parent" 411 android:layout_height="64dp" 412 android:scaleType="center" 413 android:background="#FFFFBB33" 414 android:contentDescription="@string/app_name" /> 415 <EditText 416 android:id="@+id/username" 417 android:inputType="textEmailAddress" 418 android:layout_width="match_parent" 419 android:layout_height="wrap_content" 420 android:layout_marginTop="16dp" 421 android:layout_marginLeft="4dp" 422 android:layout_marginRight="4dp" 423 android:layout_marginBottom="4dp" 424 android:hint="@string/username" /> 425 <EditText 426 android:id="@+id/password" 427 android:inputType="textPassword" 428 android:layout_width="match_parent" 429 android:layout_height="wrap_content" 430 android:layout_marginTop="4dp" 431 android:layout_marginLeft="4dp" 432 android:layout_marginRight="4dp" 433 android:layout_marginBottom="16dp" 434 android:fontFamily="sans-serif" 435 android:hint="@string/password"/> 436</LinearLayout> 437</pre> 438 439<p class="note"><strong>Mẹo:</strong> Theo mặc định, khi bạn đặt một phần tử {@link android.widget.EditText} 440để sử dụng kiểu đầu vào {@code "textPassword"}, họ phông được đặt thành đơn cách, vì thế 441bạn nên đổi họ phông thành {@code "sans-serif"} sao cho cả hai trường văn bản đều sử dụng 442một kiểu phông thống nhất.</p> 443 444<p>Để bung bố trí ra trong {@link android.support.v4.app.DialogFragment} của bạn, 445hãy lấy một {@link android.view.LayoutInflater} với 446{@link android.app.Activity#getLayoutInflater()} và gọi 447{@link android.view.LayoutInflater#inflate inflate()}, trong đó tham số đầu tiên 448là ID tài nguyên bố trí và tham số thứ hai là một dạng xem mẹ cho bố trí. 449Khi đó, bạn có thể gọi {@link android.app.AlertDialog#setView setView()} 450để đặt bố trí vào một hộp thoại.</p> 451 452<pre> 453@Override 454public Dialog onCreateDialog(Bundle savedInstanceState) { 455 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 456 // Get the layout inflater 457 LayoutInflater inflater = getActivity().getLayoutInflater(); 458 459 // Inflate and set the layout for the dialog 460 // Pass null as the parent view because its going in the dialog layout 461 builder.setView(inflater.inflate(R.layout.dialog_signin, null)) 462 // Add action buttons 463 .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() { 464 @Override 465 public void onClick(DialogInterface dialog, int id) { 466 // sign in the user ... 467 } 468 }) 469 .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 470 public void onClick(DialogInterface dialog, int id) { 471 LoginDialogFragment.this.getDialog().cancel(); 472 } 473 }); 474 return builder.create(); 475} 476</pre> 477 478<div class="note"> 479<p><strong>Mẹo:</strong> Nếu bạn muốn một hộp thoại tùy chỉnh, 480thay vào đó, bạn có thể hiển thị {@link android.app.Activity} như là một hộp thoại 481thay vì sử dụng các API {@link android.app.Dialog}. Chỉ cần tạo một hoạt động và đặt chủ đề của nó thành 482{@link android.R.style#Theme_Holo_Dialog Theme.Holo.Dialog} 483trong phần tử bản kê khai <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code 484<activity>}</a>:</p> 485 486<pre> 487<activity android:theme="@android:style/Theme.Holo.Dialog" > 488</pre> 489<p>Vậy là xong. Lúc này, hoạt động sẽ hiển thị một cửa sổ hộp thoại thay vì toàn màn hình.</p> 490</div> 491 492 493 494<h2 id="PassingEvents">Chuyển Sự kiện lại Máy chủ của Hộp thoại</h2> 495 496<p>Khi người dùng chạm vào một trong các nút hành động của hộp thoại hoặc chọn một mục từ danh sách của hộp thoại, 497{@link android.support.v4.app.DialogFragment} của bạn có thể tự thực hiện hành động 498cần thiết, nhưng thường thì bạn sẽ muốn chuyển sự kiện tới hoạt động hoặc phân đoạn 499đã mở hộp thoại. Để làm điều này, hãy định nghĩa một giao diện bằng một phương pháp cho mỗi loại sự kiện nhấp. 500Sau đó, triển khai giao diện đó trong thành phần chủ mà sẽ 501nhận sự kiện hành động từ hộp thoại.</p> 502 503<p>Ví dụ, sau đây là một {@link android.support.v4.app.DialogFragment} có chức năng định nghĩa một 504giao diện mà thông qua đó, nó sẽ chuyển các sự kiện lại cho hoạt động chủ:</p> 505 506<pre> 507public class NoticeDialogFragment extends DialogFragment { 508 509 /* The activity that creates an instance of this dialog fragment must 510 * implement this interface in order to receive event callbacks. 511 * Each method passes the DialogFragment in case the host needs to query it. */ 512 public interface NoticeDialogListener { 513 public void onDialogPositiveClick(DialogFragment dialog); 514 public void onDialogNegativeClick(DialogFragment dialog); 515 } 516 517 // Use this instance of the interface to deliver action events 518 NoticeDialogListener mListener; 519 520 // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener 521 @Override 522 public void onAttach(Activity activity) { 523 super.onAttach(activity); 524 // Verify that the host activity implements the callback interface 525 try { 526 // Instantiate the NoticeDialogListener so we can send events to the host 527 mListener = (NoticeDialogListener) activity; 528 } catch (ClassCastException e) { 529 // The activity doesn't implement the interface, throw exception 530 throw new ClassCastException(activity.toString() 531 + " must implement NoticeDialogListener"); 532 } 533 } 534 ... 535} 536</pre> 537 538<p>Hoạt động lưu giữ hộp thoại sẽ tạo một thực thể của hộp thoại 539bằng hàm dựng của phân đoạn hộp thoại và nhận sự kiện 540của hộp thoại thông qua triển khai giao diện {@code NoticeDialogListener}:</p> 541 542<pre> 543public class MainActivity extends FragmentActivity 544 implements NoticeDialogFragment.NoticeDialogListener{ 545 ... 546 547 public void showNoticeDialog() { 548 // Create an instance of the dialog fragment and show it 549 DialogFragment dialog = new NoticeDialogFragment(); 550 dialog.show(getSupportFragmentManager(), "NoticeDialogFragment"); 551 } 552 553 // The dialog fragment receives a reference to this Activity through the 554 // Fragment.onAttach() callback, which it uses to call the following methods 555 // defined by the NoticeDialogFragment.NoticeDialogListener interface 556 @Override 557 public void onDialogPositiveClick(DialogFragment dialog) { 558 // User touched the dialog's positive button 559 ... 560 } 561 562 @Override 563 public void onDialogNegativeClick(DialogFragment dialog) { 564 // User touched the dialog's negative button 565 ... 566 } 567} 568</pre> 569 570<p>Vì hoạt động chủ sẽ triển khai {@code NoticeDialogListener}—, được 571thực thi bởi phương pháp gọi lại {@link android.support.v4.app.Fragment#onAttach onAttach()} 572minh họa bên trên,—phân đoạn hộp thoại có thể sử dụng các phương pháp gọi lại 573giao diện để chuyển các sự kiện nhấp cho hoạt động:</p> 574 575<pre> 576public class NoticeDialogFragment extends DialogFragment { 577 ... 578 579 @Override 580 public Dialog onCreateDialog(Bundle savedInstanceState) { 581 // Build the dialog and set up the button click handlers 582 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 583 builder.setMessage(R.string.dialog_fire_missiles) 584 .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { 585 public void onClick(DialogInterface dialog, int id) { 586 // Send the positive button event back to the host activity 587 mListener.onDialogPositiveClick(NoticeDialogFragment.this); 588 } 589 }) 590 .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 591 public void onClick(DialogInterface dialog, int id) { 592 // Send the negative button event back to the host activity 593 mListener.onDialogNegativeClick(NoticeDialogFragment.this); 594 } 595 }); 596 return builder.create(); 597 } 598} 599</pre> 600 601 602 603<h2 id="ShowingADialog">Hiển thị một Hộp thoại</h2> 604 605<p>Khi bạn muốn hiển thị hộp thoại của mình, hãy tạo một thực thể {@link 606android.support.v4.app.DialogFragment} của bạn và gọi {@link android.support.v4.app.DialogFragment#show 607show()}, chuyển {@link android.support.v4.app.FragmentManager} và một tên tag 608cho phân đoạn hộp thoại.</p> 609 610<p>Bạn có thể nhận được {@link android.support.v4.app.FragmentManager} bằng cách gọi 611{@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()} từ 612{@link android.support.v4.app.FragmentActivity} hoặc {@link 613android.support.v4.app.Fragment#getFragmentManager()} từ một {@link 614android.support.v4.app.Fragment}. Ví dụ:</p> 615 616<pre> 617public void confirmFireMissiles() { 618 DialogFragment newFragment = new FireMissilesDialogFragment(); 619 newFragment.show(getSupportFragmentManager(), "missiles"); 620} 621</pre> 622 623<p>Tham đối thứ hai, {@code "missiles"}, là một tên tag duy nhất mà hệ thống sử dụng để lưu 624và khôi phục trạng thái của phân đoạn khi cần thiết. Tag cũng cho phép bạn nhận một điều khiển (handle) cho 625phân đoạn bằng cách gọi {@link android.support.v4.app.FragmentManager#findFragmentByTag 626findFragmentByTag()}.</p> 627 628 629 630 631<h2 id="FullscreenDialog">Hiển thị một Hộp thoại Toàn màn hình hoặc dạng một Phân đoạn Nhúng</h2> 632 633<p>Bạn có thể có một thiết kế UI mà trong đó bạn muốn một phần UI xuất hiện như một hộp thoại trong một số 634tình huống, nhưng ở dưới dạng toàn màn hình hoặc phân đoạn nhúng trong trường hợp khác (có thể phụ thuộc 635vào thiết bị là màn hình lớn hay nhỏ). Lớp {@link android.support.v4.app.DialogFragment} 636cung cấp cho bạn sự linh hoạt này vì nó vẫn có thể đóng vai trò như một {@link 637android.support.v4.app.Fragment} nhúng được.</p> 638 639<p>Tuy nhiên, bạn không thể sử dụng {@link android.app.AlertDialog.Builder AlertDialog.Builder} 640hay các đối tượng {@link android.app.Dialog} khác để xây dựng hộp thoại trong trường hợp này. Nếu 641bạn muốn {@link android.support.v4.app.DialogFragment} có thể 642nhúng được, bạn phải định nghĩa UI của hộp thoại trong một bố trí, rồi tải bố trí đó trong lệnh gọi lại 643{@link android.support.v4.app.DialogFragment#onCreateView 644onCreateView()}.</p> 645 646<p>Sau đây là một ví dụ {@link android.support.v4.app.DialogFragment} có thể xuất hiện như một 647hộp thoại hoặc phân đoạn nhúng được (sử dụng một bố trí có tên gọi <code>purchase_items.xml</code>):</p> 648 649<pre> 650public class CustomDialogFragment extends DialogFragment { 651 /** The system calls this to get the DialogFragment's layout, regardless 652 of whether it's being displayed as a dialog or an embedded fragment. */ 653 @Override 654 public View onCreateView(LayoutInflater inflater, ViewGroup container, 655 Bundle savedInstanceState) { 656 // Inflate the layout to use as dialog or embedded fragment 657 return inflater.inflate(R.layout.purchase_items, container, false); 658 } 659 660 /** The system calls this only when creating the layout in a dialog. */ 661 @Override 662 public Dialog onCreateDialog(Bundle savedInstanceState) { 663 // The only reason you might override this method when using onCreateView() is 664 // to modify any dialog characteristics. For example, the dialog includes a 665 // title by default, but your custom layout might not need it. So here you can 666 // remove the dialog title, but you must call the superclass to get the Dialog. 667 Dialog dialog = super.onCreateDialog(savedInstanceState); 668 dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 669 return dialog; 670 } 671} 672</pre> 673 674<p>Và sau đây là một số mã quyết định xem hiển thị phân đoạn như một hộp thoại 675hay UI toàn màn hình, dựa vào kích cỡ màn hình:</p> 676 677<pre> 678public void showDialog() { 679 FragmentManager fragmentManager = getSupportFragmentManager(); 680 CustomDialogFragment newFragment = new CustomDialogFragment(); 681 682 if (mIsLargeLayout) { 683 // The device is using a large layout, so show the fragment as a dialog 684 newFragment.show(fragmentManager, "dialog"); 685 } else { 686 // The device is smaller, so show the fragment fullscreen 687 FragmentTransaction transaction = fragmentManager.beginTransaction(); 688 // For a little polish, specify a transition animation 689 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 690 // To make it fullscreen, use the 'content' root view as the container 691 // for the fragment, which is always the root view for the activity 692 transaction.add(android.R.id.content, newFragment) 693 .addToBackStack(null).commit(); 694 } 695} 696</pre> 697 698<p>Để biết thêm thông tin về việc thực hiện các giao tác phân đoạn, hãy xem hướng dẫn 699<a href="{@docRoot}guide/components/fragments.html">Phân đoạn</a>.</p> 700 701<p>Trong ví dụ này, boolean <code>mIsLargeLayout</code> chỉ định liệu thiết bị hiện tại 702có nên sử dụng thiết kế bố trí lớn của ứng dụng (và vì thế, nó hiển thị phân đoạn này như một hộp thoại thay vì 703toàn màn hình) hay không. Cách tốt nhất để đặt loại boolean này đó là khai báo một 704<a href="{@docRoot}guide/topics/resources/more-resources.html#Bool">giá trị tài nguyên bool</a> 705bằng một giá trị <a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">tài nguyên thay thế</a> cho các kích cỡ màn hình khác nhau. Ví dụ, sau đây là hai 706phiên bản của tài nguyên bool cho các kích cỡ màn hình khác nhau:</p> 707 708<p class="code-caption">res/values/bools.xml</p> 709<pre> 710<!-- Default boolean values --> 711<resources> 712 <bool name="large_layout">false</bool> 713</resources> 714</pre> 715 716<p class="code-caption">res/values-large/bools.xml</p> 717<pre> 718<!-- Large screen boolean values --> 719<resources> 720 <bool name="large_layout">true</bool> 721</resources> 722</pre> 723 724<p>Khi đó, bạn có thể khởi tạo giá trị {@code mIsLargeLayout} trong phương pháp 725{@link android.app.Activity#onCreate onCreate()} của hoạt động:</p> 726 727<pre> 728boolean mIsLargeLayout; 729 730@Override 731public void onCreate(Bundle savedInstanceState) { 732 super.onCreate(savedInstanceState); 733 setContentView(R.layout.activity_main); 734 735 mIsLargeLayout = getResources().getBoolean(R.bool.large_layout); 736} 737</pre> 738 739 740 741<h3 id="ActivityAsDialog">Hiển thị một hoạt động dưới dạng một hộp thoại trên màn hình lớn</h3> 742 743<p>Thay vì hiển thị một hộp thoại thành UI toàn màn hình trên các màn hình nhỏ, bạn có thể đạt được 744kết quả tương tự bằng cách hiển thị một {@link android.app.Activity} thành một hộp thoại trên 745màn hình lớn. Phương pháp mà bạn chọn phụ thuộc vào thiết kế ứng dụng của bạn, nhưng 746việc hiển thị một hoạt động thành một hộp thoại thường có ích khi ứng dụng của bạn đã được thiết kế cho màn hình 747nhỏ và bạn muốn cải thiện trải nghiệm trên máy tính bảng bằng cách hiển thị một hoạt động có vòng đời ngắn 748thành một hộp thoại.</p> 749 750<p>Để hiển thị một hoạt động thành một hộp thoại chỉ khi trên màn hình lớn, 751hãy áp dụng chủ đề {@link android.R.style#Theme_Holo_DialogWhenLarge Theme.Holo.DialogWhenLarge} 752cho phần tử bản kê khai <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code 753<activity>}</a>:</p> 754 755<pre> 756<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" > 757</pre> 758 759<p>Để biết thêm thông tin về việc tạo kiểu cho các hoạt động của bạn bằng chủ đề, hãy xem hướng dẫn <a href="{@docRoot}guide/topics/ui/themes.html">Kiểu và Chủ đề</a>.</p> 760 761 762 763<h2 id="DismissingADialog">Bỏ một Hộp thoại</h2> 764 765<p>Khi người dùng chạm vào bất kỳ nút hành động nào được tạo bằng 766{@link android.app.AlertDialog.Builder}, hệ thống sẽ bỏ hộp thoại cho bạn.</p> 767 768<p>Hệ thống cũng bỏ hộp thoại khi người dùng chạm vào một mục trong một danh sách hộp thoại, trừ 769khi danh sách sử dụng nút chọn một hoặc hộp kiểm. Nếu không, bạn có thể bỏ thủ công hộp thoại của mình 770bằng cách gọi {@link android.support.v4.app.DialogFragment#dismiss()} trên {@link 771android.support.v4.app.DialogFragment} của bạn.</p> 772 773<p>Trong trường hợp bạn cần thực hiện các 774hành động nhất định khi hộp thoại biến mất, bạn có thể triển khai phương pháp {@link 775android.support.v4.app.DialogFragment#onDismiss onDismiss()} trong {@link 776android.support.v4.app.DialogFragment} của mình.</p> 777 778<p>Bạn cũng có thể <em>hủy bỏ</em> một hộp thoại. Đây là một sự kiện đặc biệt chỉ báo người dùng 779chủ ý rời khỏi hộp thoại mà không hoàn thành tác vụ. Điều này xảy ra nếu người dùng nhấn nút 780<em>Quay lại</em>, chạm vào màn hình ngoài vùng hộp thoại, 781hoặc nếu bạn công khai gọi {@link android.app.Dialog#cancel()} trên {@link 782android.app.Dialog} (chẳng hạn như khi hồi đáp lại một nút "Hủy bỏ" trong hộp thoại).</p> 783 784<p>Như nêu trong ví dụ bên trên, bạn có thể hồi đáp lại sự kiện hủy bỏ này bằng cách triển khai 785{@link android.support.v4.app.DialogFragment#onCancel onCancel()} trong lớp {@link 786android.support.v4.app.DialogFragment} của mình.</p> 787 788<p class="note"><strong>Lưu ý:</strong> Hệ thống sẽ gọi 789{@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} trên mỗi sự kiện mà 790gọi ra lệnh gọi lại {@link android.support.v4.app.DialogFragment#onCancel onCancel()}. Tuy nhiên, 791nếu bạn gọi {@link android.app.Dialog#dismiss Dialog.dismiss()} hoặc {@link 792android.support.v4.app.DialogFragment#dismiss DialogFragment.dismiss()}, 793hệ thống sẽ gọi {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} <em>chứ 794không phải</em> {@link android.support.v4.app.DialogFragment#onCancel onCancel()}. Vì thế, nhìn chung bạn nên 795gọi {@link android.support.v4.app.DialogFragment#dismiss dismiss()} khi người dùng nhấn nút 796<em>tích cực</em> trong hộp thoại của bạn để xóa hộp thoại khỏi dạng xem.</p> 797 798 799