| page.title=Hộp thoại |
| page.tags=alertdialog,dialogfragment |
| |
| @jd:body |
| |
| |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>Trong tài liệu này</h2> |
| <ol> |
| <li><a href="#DialogFragment">Tạo một Phân đoạn Hộp thoại</a></li> |
| <li><a href="#AlertDialog">Xây dựng một Hộp thoại Cảnh báo</a> |
| <ol> |
| <li><a href="#AddingButtons">Thêm nút</a></li> |
| <li><a href="#AddingAList">Thêm một danh sách</a></li> |
| <li><a href="#CustomLayout">Tạo một Bố trí Tùy chỉnh</a></li> |
| </ol> |
| </li> |
| <li><a href="#PassingEvents">Chuyển Sự kiện lại Máy chủ của Hộp thoại</a></li> |
| <li><a href="#ShowingADialog">Hiển thị một Hộp thoại</a></li> |
| <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> |
| <ol> |
| <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> |
| </ol> |
| </li> |
| <li><a href="#DismissingADialog">Bỏ một Hộp thoại</a></li> |
| </ol> |
| |
| <h2>Lớp khóa</h2> |
| <ol> |
| <li>{@link android.app.DialogFragment}</li> |
| <li>{@link android.app.AlertDialog}</li> |
| </ol> |
| |
| <h2>Xem thêm</h2> |
| <ol> |
| <li><a href="{@docRoot}design/building-blocks/dialogs.html">Hướng dẫn thiết kế hộp thoại</a></li> |
| <li><a href="{@docRoot}guide/topics/ui/controls/pickers.html">Bộ chọn</a> (Hộp thoại Ngày/Giờ)</li> |
| </ol> |
| </div> |
| </div> |
| |
| <p>Hộp thoại là một cửa sổ nhỏ có chức năng nhắc người dùng |
| đư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à |
| thườ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> |
| |
| <div class="note design"> |
| <p><strong>Thiết kế Hộp thoại</strong></p> |
| <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 |
| 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> |
| </div> |
| |
| <img src="{@docRoot}images/ui/dialogs.png" /> |
| |
| <p>Lớp {@link android.app.Dialog} là lớp cơ sở cho hộp thoại, nhưng bạn |
| nên tránh khởi tạo {@link android.app.Dialog} một cách trực tiếp. |
| Thay vào đó, hãy sử dụng một trong các lớp con sau:</p> |
| <dl> |
| <dt>{@link android.app.AlertDialog}</dt> |
| <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 |
| các mục có thể chọn, hoặc một bố trí tùy chỉnh.</dd> |
| <dt>{@link android.app.DatePickerDialog} hoặc {@link android.app.TimePickerDialog}</dt> |
| <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> |
| </dl> |
| |
| <div class="sidebox"> |
| <h2>Tránh ProgressDialog</h2> |
| <p>Android có một lớp hộp thoại khác gọi là |
| {@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 |
| cầ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 |
| thiết kế dành cho <a href="{@docRoot}design/building-blocks/progress.html">Tiến độ & |
| Hoạt động</a> và sử dụng một {@link android.widget.ProgressBar} trong bố trí của mình.</p> |
| </div> |
| |
| <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 |
| sử dụng một {@link android.support.v4.app.DialogFragment} làm bộ chứa cho hộp thoại của mình. |
| Lớp {@link android.support.v4.app.DialogFragment} sẽ cung cấp tất cả điều khiển mà |
| bạ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 |
| trên đối tượng {@link android.app.Dialog}.</p> |
| |
| <p>Việc sử dụng {@link android.support.v4.app.DialogFragment} để quản lý hộp thoại |
| sẽ đảm bảo rằng nó xử lý đúng các sự kiện vòng đời |
| chẳ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 |
| android.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 |
| thành phần có thể nhúng trong một UI rộng hơn, giống như một {@link |
| android.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 |
| trên các màn hình lớn và nhỏ).</p> |
| |
| <p>Các phần sau trong hướng dẫn này mô tả cách sử dụng {@link |
| android.support.v4.app.DialogFragment} kết hợp với một đối tượng {@link android.app.AlertDialog} |
| . 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 |
| <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Bộ chọn</a>.</p> |
| |
| <p class="note"><strong>Lưu ý:</strong> |
| Vì lớp {@link android.app.DialogFragment} ban đầu được bổ sung cùng với |
| Android 3.0 (API mức 11), tài liệu này mô tả cách sử dụng lớp {@link |
| android.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 |
| và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 |
| API 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ợ |
| là 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 |
| android.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 |
| thư viện hỗ trợ. Khi sử dụng thư viện hỗ trợ, |
| hãy nhớ rằng bạn nhập lớp <code>android.support.v4.app.DialogFragment</code> |
| chứ <em>không phải</em> <code>android.app.DialogFragment</code>.</p> |
| |
| |
| <h2 id="DialogFragment">Tạo một Phân đoạn Hộp thoại</h2> |
| |
| <p>Bạn có thể hoàn thành nhiều loại thiết kế hộp thoại—bao gồm |
| bố 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> |
| —bằng cách mở rộng |
| {@link android.support.v4.app.DialogFragment} và tạo một {@link android.app.AlertDialog} |
| trong phương pháp gọi lại {@link android.support.v4.app.DialogFragment#onCreateDialog |
| onCreateDialog()}.</p> |
| |
| <p>Ví dụ, sau đây là một {@link android.app.AlertDialog} cơ bản được quản lý bên trong |
| một {@link android.support.v4.app.DialogFragment}:</p> |
| |
| <pre> |
| public class FireMissilesDialogFragment extends DialogFragment { |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| // Use the Builder class for convenient dialog construction |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| builder.setMessage(R.string.dialog_fire_missiles) |
| .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // FIRE ZE MISSILES! |
| } |
| }) |
| .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // User cancelled the dialog |
| } |
| }); |
| // Create the AlertDialog object and return it |
| return builder.create(); |
| } |
| } |
| </pre> |
| |
| <div class="figure" style="width:290px;margin:0 0 0 20px"> |
| <img src="{@docRoot}images/ui/dialog_buttons.png" alt="" /> |
| <p class="img-caption"><strong>Hình 1.</strong> |
| Hộp thoại với một thông báo và hai nút hành động.</p> |
| </div> |
| |
| <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 |
| android.support.v4.app.DialogFragment#show show()} trên đối tượng đó, hộp thoại sẽ xuất hiện |
| như minh họa trong hình 1.</p> |
| |
| <p>Phần tiếp theo mô tả thêm về việc sử dụng các API {@link android.app.AlertDialog.Builder} |
| để tạo hộp thoại.</p> |
| |
| <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 |
| trong {@link android.support.v4.app.DialogFragment}, bao gồm tất cả |
| <a href="{@docRoot}guide/components/fragments.html#Lifecycle">phương pháp vòng đời phân đoạn</a> cơ bản. |
| |
| |
| |
| |
| |
| <h2 id="AlertDialog">Xây dựng một Hộp thoại Cảnh báo</h2> |
| |
| |
| <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à |
| thường là lớp hộp thoại duy nhất mà bạn sẽ cần. |
| Như đượ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> |
| |
| <div class="figure" style="width:311px;margin-top:0"> |
| <img src="{@docRoot}images/ui/dialogs_regions.png" alt="" style="margin-bottom:0" /> |
| <p class="img-caption"><strong>Hình 2.</strong> Bố trí của một hộp thoại.</p> |
| </div> |
| |
| <ol> |
| <li><b>Tiêu đề</b> |
| <p>Tiêu đề không bắt buộc và chỉ nên được sử dụng khi vùng nội dung |
| 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 |
| 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> |
| <li><b>Vùng nội dung</b> |
| <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> |
| <li><b>Nút hành động</b> |
| <p>Sẽ không có quá ba nút hành động trong một hộp thoại.</p></li> |
| </ol> |
| |
| <p>Lớp {@link android.app.AlertDialog.Builder} |
| cung cấp các API cho phép bạn tạo một {@link android.app.AlertDialog} |
| với những kiểu nội dung này, bao gồm một bố trí tùy chỉnh.</p> |
| |
| <p>Để xây dựng một {@link android.app.AlertDialog}:</p> |
| |
| <pre> |
| <b>// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor</b> |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| |
| <b>// 2. Chain together various setter methods to set the dialog characteristics</b> |
| builder.setMessage(R.string.dialog_message) |
| .setTitle(R.string.dialog_title); |
| |
| <b>// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}</b> |
| AlertDialog dialog = builder.create(); |
| </pre> |
| |
| <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 |
| sử dụng lớp {@link android.app.AlertDialog.Builder}.</p> |
| |
| |
| |
| |
| <h3 id="AddingButtons">Thêm nút</h3> |
| |
| <p>Để thêm các nút hành động như trong hình 2, |
| hãy gọi các phương pháp {@link android.app.AlertDialog.Builder#setPositiveButton setPositiveButton()} và |
| {@link android.app.AlertDialog.Builder#setNegativeButton setNegativeButton()}:</p> |
| |
| <pre style="clear:right"> |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| // Add the buttons |
| builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // User clicked OK button |
| } |
| }); |
| builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // User cancelled the dialog |
| } |
| }); |
| // Set other dialog properties |
| ... |
| |
| // Create the AlertDialog |
| AlertDialog dialog = builder.create(); |
| </pre> |
| |
| <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 |
| bởi một <a href="{@docRoot}guide/topics/resources/string-resource.html">tài nguyên xâu</a>) và một |
| {@link android.content.DialogInterface.OnClickListener} có chức năng định nghĩa hành động sẽ tiến hành |
| khi người dùng nhấn nút.</p> |
| |
| <p>Có ba nút hành động khác nhau mà bạn có thể thêm:</p> |
| <dl> |
| <dt>Tích cực</dt> |
| <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> |
| <dt>Tiêu cực</dt> |
| <dd>Bạn nên sử dụng nút này để hủy bỏ hành động.</dd> |
| <dt>Trung lập</dt> |
| <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, |
| nhưng không hẳn muốn hủy bỏ. Nó nằm ở giữa nút |
| tích cực và tiêu cực. Ví dụ, hành động có thể là "Nhắc tôi sau."</dd> |
| </dl> |
| |
| <p>Bạn chỉ có thể thêm một nút mỗi loại vào một {@link |
| android.app.AlertDialog}. Nghĩa là, bạn không thể có nhiều hơn một nút "tích cực".</p> |
| |
| |
| |
| <div class="figure" style="width:290px;margin:0 0 0 40px"> |
| <img src="{@docRoot}images/ui/dialog_list.png" alt="" /> |
| <p class="img-caption"><strong>Hình 3.</strong> |
| Hộp thoại có tiêu đề và danh sách.</p> |
| </div> |
| |
| <h3 id="AddingAList">Thêm một danh sách</h3> |
| |
| <p>Có ba loại danh sách có sẵn với các API {@link android.app.AlertDialog}:</p> |
| <ul> |
| <li>Danh sách một lựa chọn truyền thống</li> |
| <li>Danh sách một lựa chọn cố định (nút chọn một)</li> |
| <li>Danh sách nhiều lựa chọn cố định (hộp kiểm)</li> |
| </ul> |
| |
| <p>Để tạo danh sách một lựa chọn như danh sách trong hình 3, |
| hãy sử dụng phương pháp {@link android.app.AlertDialog.Builder#setItems setItems()}:</p> |
| |
| <pre style="clear:right"> |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| builder.setTitle(R.string.pick_color) |
| .setItems(R.array.colors_array, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int which) { |
| // The 'which' argument contains the index position |
| // of the selected item |
| } |
| }); |
| return builder.create(); |
| } |
| </pre> |
| |
| <p>Vì danh sách xuất hiện trong vùng nội dung của hộp thoại, |
| hộ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 |
| bằng {@link android.app.AlertDialog.Builder#setTitle setTitle()}. |
| Để chỉ định các mục cho danh sách, hãy gọi {@link |
| android.app.AlertDialog.Builder#setItems setItems()}, chuyển một mảng. |
| Hoặc, bạn có thể chỉ định một danh sách bằng cách sử dụng {@link |
| android.app.AlertDialog.Builder#setAdapter setAdapter()}. Điều này cho phép bạn hỗ trợ danh sách |
| bằ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> |
| |
| <p>Nếu bạn chọn hỗ trợ danh sách của mình bằng một {@link android.widget.ListAdapter}, |
| hãy luôn sử dụng {@link android.support.v4.content.Loader} sao cho nội dung tải |
| không đồng bộ. Điều này được mô tả thêm trong hướng dẫn |
| <a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Xây dựng Bố trí |
| bằng một Trình điều hợp</a> và <a href="{@docRoot}guide/components/loaders.html">Trình tải</a> |
| .</p> |
| |
| <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, |
| trừ khi bạn đang sử dụng một trong các danh sách lựa chọn cố định sau.</p> |
| |
| <div class="figure" style="width:290px;margin:-30px 0 0 40px"> |
| <img src="{@docRoot}images/ui/dialog_checkboxes.png" /> |
| <p class="img-caption"><strong>Hình 4.</strong> |
| Danh sách nhiều mục lựa chọn.</p> |
| </div> |
| |
| |
| <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> |
| |
| <p>Để thêm một danh sách nhiều lựa chọn (hộp kiểm) hoặc |
| một lựa chọn (nút chọn một), hãy sử dụng các phương pháp |
| {@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String, |
| DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} hoặc |
| {@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) |
| setSingleChoiceItems()} tương ứng.</p> |
| |
| <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ư |
| danh sách được minh họa trong hình 4 giúp lưu các mục |
| được chọn trong một {@link java.util.ArrayList}:</p> |
| |
| <pre style="clear:right"> |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| mSelectedItems = new ArrayList(); // Where we track the selected items |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| // Set the dialog title |
| builder.setTitle(R.string.pick_toppings) |
| // Specify the list array, the items to be selected by default (null for none), |
| // and the listener through which to receive callbacks when items are selected |
| .setMultiChoiceItems(R.array.toppings, null, |
| new DialogInterface.OnMultiChoiceClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which, |
| boolean isChecked) { |
| if (isChecked) { |
| // If the user checked the item, add it to the selected items |
| mSelectedItems.add(which); |
| } else if (mSelectedItems.contains(which)) { |
| // Else, if the item is already in the array, remove it |
| mSelectedItems.remove(Integer.valueOf(which)); |
| } |
| } |
| }) |
| // Set the action buttons |
| .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int id) { |
| // User clicked OK, so save the mSelectedItems results somewhere |
| // or return them to the component that opened the dialog |
| ... |
| } |
| }) |
| .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int id) { |
| ... |
| } |
| }); |
| |
| return builder.create(); |
| } |
| </pre> |
| |
| <p>Mặc dù cả danh sách truyền thống và danh sách có nút chọn một |
| đều cung cấp hành động "một lựa chọn", bạn nên sử dụng {@link |
| android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) |
| setSingleChoiceItems()} nếu bạn muốn cố định lựa chọn của người dùng. |
| Cụ 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 đó |
| bạn hãy tạo một danh sách với các nút chọn một.</p> |
| |
| |
| |
| |
| |
| <h3 id="CustomLayout">Tạo một Bố trí Tùy chỉnh</h3> |
| |
| <div class="figure" style="width:290px;margin:-30px 0 0 40px"> |
| <img src="{@docRoot}images/ui/dialog_custom.png" alt="" /> |
| <p class="img-caption"><strong>Hình 5.</strong> Một bố trí hộp thoại tùy chỉnh.</p> |
| </div> |
| |
| <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 |
| {@link android.app.AlertDialog} bằng cách gọi {@link |
| android.app.AlertDialog.Builder#setView setView()} trên đối tượng {@link |
| android.app.AlertDialog.Builder} của bạn.</p> |
| |
| <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ể |
| sử dụng các phương pháp {@link android.app.AlertDialog.Builder} để thêm nút và tiêu đề.</p> |
| |
| <p>Ví dụ, sau đây là tệp bố trí cho hộp thoại trong Hình 5:</p> |
| |
| <p style="clear:right" class="code-caption">res/layout/dialog_signin.xml</p> |
| <pre> |
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| android:orientation="vertical" |
| android:layout_width="wrap_content" |
| android:layout_height="wrap_content"> |
| <ImageView |
| android:src="@drawable/header_logo" |
| android:layout_width="match_parent" |
| android:layout_height="64dp" |
| android:scaleType="center" |
| android:background="#FFFFBB33" |
| android:contentDescription="@string/app_name" /> |
| <EditText |
| android:id="@+id/username" |
| android:inputType="textEmailAddress" |
| android:layout_width="match_parent" |
| android:layout_height="wrap_content" |
| android:layout_marginTop="16dp" |
| android:layout_marginLeft="4dp" |
| android:layout_marginRight="4dp" |
| android:layout_marginBottom="4dp" |
| android:hint="@string/username" /> |
| <EditText |
| android:id="@+id/password" |
| android:inputType="textPassword" |
| android:layout_width="match_parent" |
| android:layout_height="wrap_content" |
| android:layout_marginTop="4dp" |
| android:layout_marginLeft="4dp" |
| android:layout_marginRight="4dp" |
| android:layout_marginBottom="16dp" |
| android:fontFamily="sans-serif" |
| android:hint="@string/password"/> |
| </LinearLayout> |
| </pre> |
| |
| <p class="note"><strong>Mẹo:</strong> Theo mặc định, khi bạn đặt một phần tử {@link android.widget.EditText} |
| để sử dụng kiểu đầu vào {@code "textPassword"}, họ phông được đặt thành đơn cách, vì thế |
| bạ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 |
| một kiểu phông thống nhất.</p> |
| |
| <p>Để bung bố trí ra trong {@link android.support.v4.app.DialogFragment} của bạn, |
| hãy lấy một {@link android.view.LayoutInflater} với |
| {@link android.app.Activity#getLayoutInflater()} và gọi |
| {@link android.view.LayoutInflater#inflate inflate()}, trong đó tham số đầu tiên |
| là ID tài nguyên bố trí và tham số thứ hai là một dạng xem mẹ cho bố trí. |
| Khi đó, bạn có thể gọi {@link android.app.AlertDialog#setView setView()} |
| để đặt bố trí vào một hộp thoại.</p> |
| |
| <pre> |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| // Get the layout inflater |
| LayoutInflater inflater = getActivity().getLayoutInflater(); |
| |
| // Inflate and set the layout for the dialog |
| // Pass null as the parent view because its going in the dialog layout |
| builder.setView(inflater.inflate(R.layout.dialog_signin, null)) |
| // Add action buttons |
| .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int id) { |
| // sign in the user ... |
| } |
| }) |
| .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| LoginDialogFragment.this.getDialog().cancel(); |
| } |
| }); |
| return builder.create(); |
| } |
| </pre> |
| |
| <div class="note"> |
| <p><strong>Mẹo:</strong> Nếu bạn muốn một hộp thoại tùy chỉnh, |
| thay vào đó, bạn có thể hiển thị {@link android.app.Activity} như là một hộp thoại |
| thay 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 |
| {@link android.R.style#Theme_Holo_Dialog Theme.Holo.Dialog} |
| trong phần tử bản kê khai <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code |
| <activity>}</a>:</p> |
| |
| <pre> |
| <activity android:theme="@android:style/Theme.Holo.Dialog" > |
| </pre> |
| <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> |
| </div> |
| |
| |
| |
| <h2 id="PassingEvents">Chuyển Sự kiện lại Máy chủ của Hộp thoại</h2> |
| |
| <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, |
| {@link android.support.v4.app.DialogFragment} của bạn có thể tự thực hiện hành động |
| cầ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 |
| đã 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. |
| Sau đó, triển khai giao diện đó trong thành phần chủ mà sẽ |
| nhận sự kiện hành động từ hộp thoại.</p> |
| |
| <p>Ví dụ, sau đây là một {@link android.support.v4.app.DialogFragment} có chức năng định nghĩa một |
| giao diện mà thông qua đó, nó sẽ chuyển các sự kiện lại cho hoạt động chủ:</p> |
| |
| <pre> |
| public class NoticeDialogFragment extends DialogFragment { |
| |
| /* The activity that creates an instance of this dialog fragment must |
| * implement this interface in order to receive event callbacks. |
| * Each method passes the DialogFragment in case the host needs to query it. */ |
| public interface NoticeDialogListener { |
| public void onDialogPositiveClick(DialogFragment dialog); |
| public void onDialogNegativeClick(DialogFragment dialog); |
| } |
| |
| // Use this instance of the interface to deliver action events |
| NoticeDialogListener mListener; |
| |
| // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener |
| @Override |
| public void onAttach(Activity activity) { |
| super.onAttach(activity); |
| // Verify that the host activity implements the callback interface |
| try { |
| // Instantiate the NoticeDialogListener so we can send events to the host |
| mListener = (NoticeDialogListener) activity; |
| } catch (ClassCastException e) { |
| // The activity doesn't implement the interface, throw exception |
| throw new ClassCastException(activity.toString() |
| + " must implement NoticeDialogListener"); |
| } |
| } |
| ... |
| } |
| </pre> |
| |
| <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 |
| bằng hàm dựng của phân đoạn hộp thoại và nhận sự kiện |
| của hộp thoại thông qua triển khai giao diện {@code NoticeDialogListener}:</p> |
| |
| <pre> |
| public class MainActivity extends FragmentActivity |
| implements NoticeDialogFragment.NoticeDialogListener{ |
| ... |
| |
| public void showNoticeDialog() { |
| // Create an instance of the dialog fragment and show it |
| DialogFragment dialog = new NoticeDialogFragment(); |
| dialog.show(getSupportFragmentManager(), "NoticeDialogFragment"); |
| } |
| |
| // The dialog fragment receives a reference to this Activity through the |
| // Fragment.onAttach() callback, which it uses to call the following methods |
| // defined by the NoticeDialogFragment.NoticeDialogListener interface |
| @Override |
| public void onDialogPositiveClick(DialogFragment dialog) { |
| // User touched the dialog's positive button |
| ... |
| } |
| |
| @Override |
| public void onDialogNegativeClick(DialogFragment dialog) { |
| // User touched the dialog's negative button |
| ... |
| } |
| } |
| </pre> |
| |
| <p>Vì hoạt động chủ sẽ triển khai {@code NoticeDialogListener}—, được |
| thực thi bởi phương pháp gọi lại {@link android.support.v4.app.Fragment#onAttach onAttach()} |
| minh 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 |
| giao diện để chuyển các sự kiện nhấp cho hoạt động:</p> |
| |
| <pre> |
| public class NoticeDialogFragment extends DialogFragment { |
| ... |
| |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| // Build the dialog and set up the button click handlers |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| builder.setMessage(R.string.dialog_fire_missiles) |
| .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // Send the positive button event back to the host activity |
| mListener.onDialogPositiveClick(NoticeDialogFragment.this); |
| } |
| }) |
| .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // Send the negative button event back to the host activity |
| mListener.onDialogNegativeClick(NoticeDialogFragment.this); |
| } |
| }); |
| return builder.create(); |
| } |
| } |
| </pre> |
| |
| |
| |
| <h2 id="ShowingADialog">Hiển thị một Hộp thoại</h2> |
| |
| <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 |
| android.support.v4.app.DialogFragment} của bạn và gọi {@link android.support.v4.app.DialogFragment#show |
| show()}, chuyển {@link android.support.v4.app.FragmentManager} và một tên tag |
| cho phân đoạn hộp thoại.</p> |
| |
| <p>Bạn có thể nhận được {@link android.support.v4.app.FragmentManager} bằng cách gọi |
| {@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()} từ |
| {@link android.support.v4.app.FragmentActivity} hoặc {@link |
| android.support.v4.app.Fragment#getFragmentManager()} từ một {@link |
| android.support.v4.app.Fragment}. Ví dụ:</p> |
| |
| <pre> |
| public void confirmFireMissiles() { |
| DialogFragment newFragment = new FireMissilesDialogFragment(); |
| newFragment.show(getSupportFragmentManager(), "missiles"); |
| } |
| </pre> |
| |
| <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 |
| và 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 |
| phân đoạn bằng cách gọi {@link android.support.v4.app.FragmentManager#findFragmentByTag |
| findFragmentByTag()}.</p> |
| |
| |
| |
| |
| <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> |
| |
| <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ố |
| tì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 |
| vào thiết bị là màn hình lớn hay nhỏ). Lớp {@link android.support.v4.app.DialogFragment} |
| cung cấp cho bạn sự linh hoạt này vì nó vẫn có thể đóng vai trò như một {@link |
| android.support.v4.app.Fragment} nhúng được.</p> |
| |
| <p>Tuy nhiên, bạn không thể sử dụng {@link android.app.AlertDialog.Builder AlertDialog.Builder} |
| hay 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 |
| bạn muốn {@link android.support.v4.app.DialogFragment} có thể |
| nhú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 |
| {@link android.support.v4.app.DialogFragment#onCreateView |
| onCreateView()}.</p> |
| |
| <p>Sau đây là một ví dụ {@link android.support.v4.app.DialogFragment} có thể xuất hiện như một |
| hộ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> |
| |
| <pre> |
| public class CustomDialogFragment extends DialogFragment { |
| /** The system calls this to get the DialogFragment's layout, regardless |
| of whether it's being displayed as a dialog or an embedded fragment. */ |
| @Override |
| public View onCreateView(LayoutInflater inflater, ViewGroup container, |
| Bundle savedInstanceState) { |
| // Inflate the layout to use as dialog or embedded fragment |
| return inflater.inflate(R.layout.purchase_items, container, false); |
| } |
| |
| /** The system calls this only when creating the layout in a dialog. */ |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| // The only reason you might override this method when using onCreateView() is |
| // to modify any dialog characteristics. For example, the dialog includes a |
| // title by default, but your custom layout might not need it. So here you can |
| // remove the dialog title, but you must call the superclass to get the Dialog. |
| Dialog dialog = super.onCreateDialog(savedInstanceState); |
| dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); |
| return dialog; |
| } |
| } |
| </pre> |
| |
| <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 |
| hay UI toàn màn hình, dựa vào kích cỡ màn hình:</p> |
| |
| <pre> |
| public void showDialog() { |
| FragmentManager fragmentManager = getSupportFragmentManager(); |
| CustomDialogFragment newFragment = new CustomDialogFragment(); |
| |
| if (mIsLargeLayout) { |
| // The device is using a large layout, so show the fragment as a dialog |
| newFragment.show(fragmentManager, "dialog"); |
| } else { |
| // The device is smaller, so show the fragment fullscreen |
| FragmentTransaction transaction = fragmentManager.beginTransaction(); |
| // For a little polish, specify a transition animation |
| transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); |
| // To make it fullscreen, use the 'content' root view as the container |
| // for the fragment, which is always the root view for the activity |
| transaction.add(android.R.id.content, newFragment) |
| .addToBackStack(null).commit(); |
| } |
| } |
| </pre> |
| |
| <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 |
| <a href="{@docRoot}guide/components/fragments.html">Phân đoạn</a>.</p> |
| |
| <p>Trong ví dụ này, boolean <code>mIsLargeLayout</code> chỉ định liệu thiết bị hiện tại |
| có 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ì |
| toà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 |
| <a href="{@docRoot}guide/topics/resources/more-resources.html#Bool">giá trị tài nguyên bool</a> |
| bằ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 |
| phiên bản của tài nguyên bool cho các kích cỡ màn hình khác nhau:</p> |
| |
| <p class="code-caption">res/values/bools.xml</p> |
| <pre> |
| <!-- Default boolean values --> |
| <resources> |
| <bool name="large_layout">false</bool> |
| </resources> |
| </pre> |
| |
| <p class="code-caption">res/values-large/bools.xml</p> |
| <pre> |
| <!-- Large screen boolean values --> |
| <resources> |
| <bool name="large_layout">true</bool> |
| </resources> |
| </pre> |
| |
| <p>Khi đó, bạn có thể khởi tạo giá trị {@code mIsLargeLayout} trong phương pháp |
| {@link android.app.Activity#onCreate onCreate()} của hoạt động:</p> |
| |
| <pre> |
| boolean mIsLargeLayout; |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| setContentView(R.layout.activity_main); |
| |
| mIsLargeLayout = getResources().getBoolean(R.bool.large_layout); |
| } |
| </pre> |
| |
| |
| |
| <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> |
| |
| <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 |
| kế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 |
| mà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 |
| việ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 |
| nhỏ 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 |
| thành một hộp thoại.</p> |
| |
| <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, |
| hãy áp dụng chủ đề {@link android.R.style#Theme_Holo_DialogWhenLarge Theme.Holo.DialogWhenLarge} |
| cho phần tử bản kê khai <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code |
| <activity>}</a>:</p> |
| |
| <pre> |
| <activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" > |
| </pre> |
| |
| <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> |
| |
| |
| |
| <h2 id="DismissingADialog">Bỏ một Hộp thoại</h2> |
| |
| <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 |
| {@link android.app.AlertDialog.Builder}, hệ thống sẽ bỏ hộp thoại cho bạn.</p> |
| |
| <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ừ |
| khi 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 |
| bằng cách gọi {@link android.support.v4.app.DialogFragment#dismiss()} trên {@link |
| android.support.v4.app.DialogFragment} của bạn.</p> |
| |
| <p>Trong trường hợp bạn cần thực hiện các |
| hà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 |
| android.support.v4.app.DialogFragment#onDismiss onDismiss()} trong {@link |
| android.support.v4.app.DialogFragment} của mình.</p> |
| |
| <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 |
| chủ ý 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 |
| <em>Quay lại</em>, chạm vào màn hình ngoài vùng hộp thoại, |
| hoặc nếu bạn công khai gọi {@link android.app.Dialog#cancel()} trên {@link |
| android.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> |
| |
| <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 |
| {@link android.support.v4.app.DialogFragment#onCancel onCancel()} trong lớp {@link |
| android.support.v4.app.DialogFragment} của mình.</p> |
| |
| <p class="note"><strong>Lưu ý:</strong> Hệ thống sẽ gọi |
| {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} trên mỗi sự kiện mà |
| gọi ra lệnh gọi lại {@link android.support.v4.app.DialogFragment#onCancel onCancel()}. Tuy nhiên, |
| nếu bạn gọi {@link android.app.Dialog#dismiss Dialog.dismiss()} hoặc {@link |
| android.support.v4.app.DialogFragment#dismiss DialogFragment.dismiss()}, |
| hệ thống sẽ gọi {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} <em>chứ |
| không phải</em> {@link android.support.v4.app.DialogFragment#onCancel onCancel()}. Vì thế, nhìn chung bạn nên |
| gọi {@link android.support.v4.app.DialogFragment#dismiss dismiss()} khi người dùng nhấn nút |
| <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> |
| |
| |