Hộp thoại là một cửa sổ nhỏ nhắc người dùng thực hiện hoặc nhập thông tin bổ sung. Một hộp thoại không lấp đầy màn hình và thường được dùng cho các sự kiện phương thức yêu cầu người dùng phải thực hiện hành động trước họ có thể tiếp tục.
Dialog
là lớp cơ sở cho hộp thoại, nhưng không tạo thực thể Dialog
trực tiếp. Thay vào đó, hãy sử dụng một trong các lớp con sau:
AlertDialog
- Một hộp thoại có thể hiển thị tiêu đề, tối đa 3 nút và một danh sách các mục hoặc bố cục tùy chỉnh.
DatePickerDialog
hoặcTimePickerDialog
- Hộp thoại có giao diện người dùng được xác định trước cho phép người dùng chọn ngày hoặc bất cứ lúc nào.
Các lớp này xác định kiểu và cấu trúc cho hộp thoại của bạn. Bạn cũng cần
một
DialogFragment
làm vùng chứa cho hộp thoại. Lớp DialogFragment
cung cấp
tất cả các nút điều khiển bạn cần để tạo hộp thoại và quản lý giao diện của hộp thoại đó,
thay vì gọi các phương thức trên đối tượng Dialog
.
Việc sử dụng DialogFragment
để quản lý hộp thoại giúp hộp thoại trở nên chính xác
xử lý các sự kiện trong vòng đời như khi người dùng nhấn vào nút Quay lại hoặc xoay
màn hình. Lớp DialogFragment
cũng cho phép bạn sử dụng lại
giao diện người dùng của hộp thoại dưới dạng thành phần có thể nhúng trong giao diện người dùng lớn hơn—giống như
truyền thống
Fragment
—ví dụ như
chẳng hạn như khi bạn muốn giao diện người dùng của hộp thoại xuất hiện
khác nhau trên màn hình lớn và nhỏ
màn hình.
Các phần sau trong tài liệu này mô tả cách sử dụng
DialogFragment
kết hợp với AlertDialog
. Nếu bạn muốn tạo bộ chọn ngày hoặc giờ, hãy đọc
Thêm bộ chọn vào
ứng dụng.
Tạo mảnh hộp thoại
Bạn có thể thực hiện nhiều thiết kế hộp thoại, bao gồm cả
và những bố cục được mô tả trong
Material Design
Hộp thoại – bằng cách mở rộng DialogFragment
và tạo một
AlertDialog
trong
onCreateDialog()
phương thức gọi lại.
Ví dụ: đây là một AlertDialog
cơ bản được quản lý trong
DialogFragment
:
Kotlin
class StartGameDialogFragment : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { // Use the Builder class for convenient dialog construction. val builder = AlertDialog.Builder(it) builder.setMessage("Start game") .setPositiveButton("Start") { dialog, id -> // START THE GAME! } .setNegativeButton("Cancel") { dialog, id -> // User cancelled the dialog. } // Create the AlertDialog object and return it. builder.create() } ?: throw IllegalStateException("Activity cannot be null") } } class OldXmlActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_old_xml) StartGameDialogFragment().show(supportFragmentManager, "GAME_DIALOG") } }
Java
public class StartGameDialogFragment 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_start_game) .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // START THE GAME! } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancels the dialog. } }); // Create the AlertDialog object and return it. return builder.create(); } } // ... StartGameDialogFragment().show(supportFragmentManager, "GAME_DIALOG");
Khi bạn tạo một thực thể của lớp này và gọi
show()
trên đối tượng đó, hộp thoại sẽ xuất hiện như minh hoạ trong hình sau.
Phần tiếp theo cung cấp thêm thông tin chi tiết về cách sử dụng
AlertDialog.Builder
API để tạo hộp thoại.
Tuỳ thuộc vào độ phức tạp của hộp thoại, bạn có thể triển khai nhiều
các phương thức gọi lại khác trong DialogFragment
, bao gồm tất cả phương thức
các phương thức cơ bản trong vòng đời mảnh.
Tạo hộp thoại cảnh báo
Lớp AlertDialog
cho phép bạn tạo nhiều hộp thoại
và thường là lớp hộp thoại duy nhất bạn cần. Như được minh hoạ trong
hình minh hoạ, có 3 vùng của hộp thoại cảnh báo:
- Tiêu đề: thành phần này không bắt buộc và chỉ được sử dụng khi vùng nội dung là hiển thị trong một thông báo chi tiết, danh sách hoặc bố cục tuỳ chỉnh. Nếu bạn cần nêu một thông điệp hoặc câu hỏi đơn giản, bạn không cần tiêu đề.
- Vùng nội dung:khu vực này có thể hiển thị thông báo, danh sách hoặc của bạn.
- Nút hành động: có thể có tối đa 3 nút hành động trong một nút .
Lớp AlertDialog.Builder
cung cấp các API cho phép bạn tạo
AlertDialog
có các loại nội dung này, bao gồm cả thẻ tuỳ chỉnh
của bạn.
Để tạo AlertDialog
, hãy làm như sau:
Kotlin
val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder .setMessage("I am the message") .setTitle("I am the title") val dialog: AlertDialog = builder.create() dialog.show()
Java
// 1. Instantiate an AlertDialog.Builder with its constructor. AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // 2. Chain together various setter methods to set the dialog characteristics. builder.setMessage(R.string.dialog_message) .setTitle(R.string.dialog_title); // 3. Get the AlertDialog. AlertDialog dialog = builder.create();
Đoạn mã trước đó sẽ tạo hộp thoại này:
Thêm nút
Để thêm các nút hành động như các nút trong hình 2, hãy gọi phương thức
setPositiveButton()
và
setNegativeButton()
phương thức:
Kotlin
val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder .setMessage("I am the message") .setTitle("I am the title") .setPositiveButton("Positive") { dialog, which -> // Do something. } .setNegativeButton("Negative") { dialog, which -> // Do something else. } val dialog: AlertDialog = builder.create() dialog.show()
Java
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 taps OK button. } }); builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancels the dialog. } }); // Set other dialog properties. ... // Create the AlertDialog. AlertDialog dialog = builder.create();
Các phương thức set...Button()
yêu cầu tiêu đề cho
nút—được cung cấp bởi một
tài nguyên chuỗi và
một
DialogInterface.OnClickListener
giúp xác định hành động cần thực hiện khi người dùng nhấn vào nút.
Bạn có thể thêm 3 nút hành động sau:
- Khẳng định:sử dụng nút này để chấp nhận và tiếp tục hành động ( "OK" hành động).
- Âm: sử dụng thuộc tính này để huỷ hành động.
- Bình thường: sử dụng ngôn ngữ này khi người dùng có thể không muốn tiếp tục nhưng không nhất thiết muốn huỷ. Nó xuất hiện 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."
Bạn chỉ có thể thêm 1 nút của mỗi loại nút vào AlertDialog
. Cho
ví dụ: bạn không thể có nhiều hơn một thông báo "tích cực" .
Đoạn mã trước đó cung cấp cho bạn một hộp thoại cảnh báo như sau:
Thêm danh sách
Có 3 loại danh sách có sẵn với AlertDialog
API:
- Danh sách truyền thống chỉ có một lựa chọn.
- Một danh sách cố định có một lựa chọn (nút chọn).
- Một danh sách dạng trắc nghiệm cố định (hộp đánh dấu).
Để tạo danh sách có một lựa chọn như danh sách trong hình 5, hãy sử dụng
setItems()
phương thức:
Kotlin
val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder .setTitle("I am the title") .setPositiveButton("Positive") { dialog, which -> // Do something. } .setNegativeButton("Negative") { dialog, which -> // Do something else. } .setItems(arrayOf("Item One", "Item Two", "Item Three")) { dialog, which -> // Do something on item tapped. } val dialog: AlertDialog = builder.create() dialog.show()
Java
@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(); }
Đoạn mã này sẽ tạo một hộp thoại như sau:
Vì danh sách xuất hiện trong vùng nội dung của hộp thoại nên hộp thoại không thể hiển thị
cả thư và danh sách. Đặt tiêu đề cho hộp thoại bằng
setTitle()
.
Để chỉ định các mục cho danh sách, hãy gọi setItems()
, truyền tham số
. Ngoài ra, bạn có thể chỉ định danh sách bằng cách sử dụng
setAdapter()
.
Điều này cho phép bạn sao lưu danh sách có dữ liệu động—chẳng hạn như từ một
bằng cách sử dụng
ListAdapter
.
Nếu bạn sao lưu danh sách bằng ListAdapter
, hãy luôn sử dụng
Loader
để nội dung tải không đồng bộ. Điều này được mô tả kỹ hơn trong
Tạo bố cục
với một bộ chuyển đổi và
Trình tải.
Thêm danh sách cố định gồm một hoặc nhiều lựa chọn
Để thêm danh sách các mục có nhiều lựa chọn (hộp đánh dấu) hoặc các mục có một lựa chọn
(nút chọn), hãy sử dụng
setMultiChoiceItems()
hoặc
setSingleChoiceItems()
tương ứng.
Ví dụ: dưới đây là cách bạn có thể tạo một danh sách có nhiều lựa chọn như danh sách
như trong hình 6 để lưu các mục đã chọn trong một
ArrayList
:
Kotlin
val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder .setTitle("I am the title") .setPositiveButton("Positive") { dialog, which -> // Do something. } .setNegativeButton("Negative") { dialog, which -> // Do something else. } .setMultiChoiceItems( arrayOf("Item One", "Item Two", "Item Three"), null) { dialog, which, isChecked -> // Do something. } val dialog: AlertDialog = builder.create() dialog.show()
Java
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { selectedItems = 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 checks the item, add it to the selected // items. selectedItems.add(which); } else if (selectedItems.contains(which)) { // If the item is already in the array, remove it. selectedItems.remove(which); } } }) // Set the action buttons .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { // User taps OK, so save the selectedItems results // somewhere or return them to the component that opens the // dialog. ... } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { ... } }); return builder.create(); }
Có thể nhận được hộp thoại cảnh báo có một lựa chọn như sau:
Kotlin
val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder .setTitle("I am the title") .setPositiveButton("Positive") { dialog, which -> // Do something. } .setNegativeButton("Negative") { dialog, which -> // Do something else. } .setSingleChoiceItems( arrayOf("Item One", "Item Two", "Item Three"), 0 ) { dialog, which -> // Do something. } val dialog: AlertDialog = builder.create() dialog.show()
Java
String[] choices = {"Item One", "Item Two", "Item Three"}; AlertDialog.Builder builder = AlertDialog.Builder(context); builder .setTitle("I am the title") .setPositiveButton("Positive", (dialog, which) -> { }) .setNegativeButton("Negative", (dialog, which) -> { }) .setSingleChoiceItems(choices, 0, (dialog, which) -> { }); AlertDialog dialog = builder.create(); dialog.show();
Điều này dẫn đến ví dụ sau:
Tạo bố cục tuỳ chỉnh
Nếu bạn muốn có bố cục tuỳ chỉnh trong hộp thoại, hãy tạo bố cục và thêm bố cục đó vào
AlertDialog
bằng cách gọi
setView()
trên đối tượng AlertDialog.Builder
của bạn.
Theo mặc định, bố cục tuỳ chỉnh sẽ lấp đầy cửa sổ hộp thoại, nhưng bạn vẫn có thể sử dụng
Phương thức AlertDialog.Builder
để thêm nút và tiêu đề.
Ví dụ: đây là tệp bố cục cho hộp thoại tuỳ chỉnh trước đó bố cục:
<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>
Để tăng cường bố cục trong DialogFragment
, hãy tải
LayoutInflater
thông qua tính năng
getLayoutInflater()
và gọi
inflate()
.
Tham số đầu tiên là mã nhận dạng tài nguyên bố cục và tham số thứ hai là mã
chế độ xem gốc cho bố cục. Sau đó, bạn có thể gọi
setView()
để đặt bố cục trong hộp thoại. Lệnh này được minh hoạ trong ví dụ sau:
Kotlin
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { val builder = AlertDialog.Builder(it) // Get the layout inflater. val inflater = requireActivity().layoutInflater; // Inflate and set the layout for the dialog. // Pass null as the parent view because it's going in the dialog // layout. builder.setView(inflater.inflate(R.layout.dialog_signin, null)) // Add action buttons. .setPositiveButton(R.string.signin, DialogInterface.OnClickListener { dialog, id -> // Sign in the user. }) .setNegativeButton(R.string.cancel, DialogInterface.OnClickListener { dialog, id -> getDialog().cancel() }) builder.create() } ?: throw IllegalStateException("Activity cannot be null") }
Java
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // Get the layout inflater. LayoutInflater inflater = requireActivity().getLayoutInflater(); // Inflate and set the layout for the dialog. // Pass null as the parent view because it's 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(); }
Nếu muốn dùng hộp thoại tuỳ chỉnh, bạn có thể hiển thị
Activity
với tư cách là
thay vì sử dụng API Dialog
. Tạo một hoạt động và
đặt chủ đề thành
Theme.Holo.Dialog
trong
<activity>
phần tử tệp kê khai:
<activity android:theme="@android:style/Theme.Holo.Dialog" >
Hoạt động giờ sẽ hiển thị trong cửa sổ hộp thoại thay vì hiển thị toàn màn hình.
Chuyển các sự kiện trở lại máy chủ hộp thoại
Khi người dùng nhấn 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, DialogFragment
của bạn có thể thực hiện những việc cần thiết
hành động, nhưng thông thường bạn muốn cung cấp sự kiện cho hoạt động hoặc
mở hộp thoại. Để thực hiện việc này, hãy xác định một giao diện có phương thức
cho từng loại sự kiện nhấp chuột. Sau đó, hãy triển khai giao diện đó trong máy chủ lưu trữ
nhận các sự kiện hành động từ hộp thoại.
Ví dụ: đây là DialogFragment
xác định một giao diện
qua đó nó phân phối sự kiện trở lại hoạt động lưu trữ:
Kotlin
class NoticeDialogFragment : DialogFragment() { // Use this instance of the interface to deliver action events. internal lateinit var listener: NoticeDialogListener // The activity that creates an instance of this dialog fragment must // implement this interface to receive event callbacks. Each method passes // the DialogFragment in case the host needs to query it. interface NoticeDialogListener { fun onDialogPositiveClick(dialog: DialogFragment) fun onDialogNegativeClick(dialog: DialogFragment) } // Override the Fragment.onAttach() method to instantiate the // NoticeDialogListener. override fun onAttach(context: Context) { super.onAttach(context) // Verify that the host activity implements the callback interface. try { // Instantiate the NoticeDialogListener so you can send events to // the host. listener = context as NoticeDialogListener } catch (e: ClassCastException) { // The activity doesn't implement the interface. Throw exception. throw ClassCastException((context.toString() + " must implement NoticeDialogListener")) } } }
Java
public class NoticeDialogFragment extends DialogFragment { // The activity that creates an instance of this dialog fragment must // implement this interface 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 listener; // Override the Fragment.onAttach() method to instantiate the // NoticeDialogListener. @Override public void onAttach(Context context) { super.onAttach(context); // Verify that the host activity implements the callback interface. try { // Instantiate the NoticeDialogListener so you can send events to // the host. listener = (NoticeDialogListener) context; } catch (ClassCastException e) { // The activity doesn't implement the interface. Throw exception. throw new ClassCastException(activity.toString() + " must implement NoticeDialogListener"); } } ... }
Hoạt động lưu trữ hộp thoại sẽ tạo một phiên bản của hộp thoại có
hàm khởi tạo của mảnh hộp thoại và nhận các sự kiện của hộp thoại thông qua
cách triển khai giao diện NoticeDialogListener
:
Kotlin
class MainActivity : FragmentActivity(), NoticeDialogFragment.NoticeDialogListener { fun showNoticeDialog() { // Create an instance of the dialog fragment and show it. val dialog = NoticeDialogFragment() dialog.show(supportFragmentManager, "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 fun onDialogPositiveClick(dialog: DialogFragment) { // User taps the dialog's positive button. } override fun onDialogNegativeClick(dialog: DialogFragment) { // User taps the dialog's negative button. } }
Java
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 taps the dialog's positive button. ... } @Override public void onDialogNegativeClick(DialogFragment dialog) { // User taps the dialog's negative button. ... } }
Vì hoạt động lưu trữ triển khai
NoticeDialogListener
– được thực thi bằng
onAttach()
trong ví dụ trước – mảnh hộp thoại có thể
sử dụng phương thức gọi lại giao diện để gửi các sự kiện nhấp chuột đến hoạt động:
Kotlin
override fun onCreateDialog(savedInstanceState: Bundle): Dialog { return activity?.let { // Build the dialog and set up the button click handlers. val builder = AlertDialog.Builder(it) builder.setMessage(R.string.dialog_start_game) .setPositiveButton(R.string.start, DialogInterface.OnClickListener { dialog, id -> // Send the positive button event back to the // host activity. listener.onDialogPositiveClick(this) }) .setNegativeButton(R.string.cancel, DialogInterface.OnClickListener { dialog, id -> // Send the negative button event back to the // host activity. listener.onDialogNegativeClick(this) }) builder.create() } ?: throw IllegalStateException("Activity cannot be null") }
Java
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_start_game) .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // Send the positive button event back to the host activity. listener.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. listener.onDialogNegativeClick(NoticeDialogFragment.this); } }); return builder.create(); } }
Hiện hộp thoại
Khi bạn muốn hiển thị hộp thoại, hãy tạo một phiên bản
DialogFragment
và gọi
show()
,
truyền
FragmentManager
và tên thẻ cho mảnh hộp thoại.
Bạn có thể nhận FragmentManager
bằng cách gọi
getSupportFragmentManager()
từ
FragmentActivity
hoặc bằng cách gọi điện
getParentFragmentManager()
từ Fragment
. Hãy xem ví dụ sau đây:
Kotlin
fun confirmStartGame() { val newFragment = StartGameDialogFragment() newFragment.show(supportFragmentManager, "game") }
Java
public void confirmStartGame() { DialogFragment newFragment = new StartGameDialogFragment(); newFragment.show(getSupportFragmentManager(), "game"); }
Đối số thứ hai, "game"
, là một tên thẻ duy nhất mà
hệ thống sử dụng để lưu và khôi phục trạng thái mảnh khi cần thiết. Thẻ này cũng
cho phép bạn xử lý mảnh bằng cách gọi
findFragmentByTag()
.
Hiển thị hộp thoại ở chế độ toàn màn hình hoặc dưới dạng mảnh được nhúng
Có thể bạn muốn một phần thiết kế giao diện người dùng xuất hiện dưới dạng hộp thoại trong một số
và dưới dạng toàn màn hình hoặc mảnh được nhúng trong các tình huống khác. Bạn cũng có thể
muốn hình ảnh hiển thị khác nhau tuỳ thuộc vào kích thước màn hình của thiết bị. Chiến lược phát hành đĩa đơn
DialogFragment
lớp giúp bạn linh hoạt thực hiện việc này,
vì nó hoạt động như một Fragment
có thể nhúng.
Tuy nhiên, bạn không thể dùng AlertDialog.Builder
hoặc
Dialog
để tạo hộp thoại trong trường hợp này. Nếu bạn muốn
DialogFragment
có thể nhúng được, hãy xác định giao diện người dùng của hộp thoại trong một
sau đó tải bố cục trong
onCreateView()
.
Dưới đây là ví dụ về DialogFragment
có thể xuất hiện dưới dạng hộp thoại hoặc
một mảnh có thể nhúng, dùng một bố cục có tên
purchase_items.xml
:
Kotlin
class CustomDialogFragment : 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 fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // Inflate the layout to use as a 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 fun onCreateDialog(savedInstanceState: Bundle): Dialog { // The only reason you might override this method when using // onCreateView() is to modify the dialog characteristics. For example, // the dialog includes a title by default, but your custom layout might // not need it. Here, you can remove the dialog title, but you must // call the superclass to get the Dialog. val dialog = super.onCreateDialog(savedInstanceState) dialog.requestWindowFeature(Window.FEATURE_NO_TITLE) return dialog } }
Java
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 a 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 the dialog characteristics. For example, // the dialog includes a title by default, but your custom layout might // not need it. 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; } }
Ví dụ sau đây sẽ xác định xem sẽ hiển thị mảnh dưới dạng hộp thoại hay giao diện người dùng toàn màn hình, dựa vào kích thước màn hình:
Kotlin
fun showDialog() { val fragmentManager = supportFragmentManager val newFragment = CustomDialogFragment() if (isLargeLayout) { // 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. val transaction = fragmentManager.beginTransaction() // For a polished look, 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() } }
Java
public void showDialog() { FragmentManager fragmentManager = getSupportFragmentManager(); CustomDialogFragment newFragment = new CustomDialogFragment(); if (isLargeLayout) { // 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 polished look, 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(); } }
Để biết thêm thông tin về cách thực hiện giao dịch mảnh, hãy xem Mảnh.
Trong ví dụ này, boolean mIsLargeLayout
chỉ định liệu
thiết bị hiện tại phải sử dụng thiết kế bố cục lớn của ứng dụng, do đó, điều này
phân mảnh dưới dạng hộp thoại thay vì chế độ toàn màn hình. Cách tốt nhất để đặt loại
boolean là khai báo một
tài nguyên bool
có giá trị
phương án thay thế
tài nguyên cho nhiều kích thước màn hình. Ví dụ: dưới đây là 2
phiên bản của tài nguyên bool cho nhiều kích thước màn hình:
<!-- Default boolean values --> <resources> <bool name="large_layout">false</bool> </resources>
<!-- Large screen boolean values --> <resources> <bool name="large_layout">true</bool> </resources>
Sau đó, bạn có thể khởi tạo giá trị mIsLargeLayout
trong
của hoạt động
onCreate()
như được thể hiện trong ví dụ sau:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) isLargeLayout = resources.getBoolean(R.bool.large_layout) }
Java
boolean isLargeLayout; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); isLargeLayout = getResources().getBoolean(R.bool.large_layout); }
Hiển thị hoạt động dưới dạng hộp thoại trên màn hình lớn
Thay vì hiển thị hộp thoại dưới dạng giao diện người dùng toàn màn hình trên màn hình nhỏ, bạn có thể xem
kết quả tương tự bằng cách hiển thị Activity
dưới dạng hộp thoại trên
màn hình. Phương pháp mà bạn chọn phụ thuộc vào thiết kế của ứng dụng, nhưng việc thể hiện
hoạt động dưới dạng hộp thoại thường hữu ích khi ứng dụng của bạn được thiết kế cho các
màn hì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 ngắn hạn dưới dạng một hộp thoại.
Để chỉ hiển thị một hoạt động dưới dạng hộp thoại trên màn hình lớn, hãy áp dụng
Theme.Holo.DialogWhenLarge
giao diện cho phần tử tệp kê khai <activity>
:
<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" >
Để biết thêm thông tin về cách tạo kiểu cho hoạt động bằng giao diện, hãy xem Kiểu và giao diện.
Đóng hộp thoại
Khi người dùng nhấn vào một nút hành động được tạo bằng
AlertDialog.Builder
, hệ thống sẽ đóng hộp thoại cho bạn.
Hệ thống cũng sẽ đóng hộp thoại khi người dùng nhấn vào một mục trong hộp thoại
danh sách, trừ khi danh sách sử dụng các nút chọn hoặc hộp đánh dấu. Nếu không, bạn có thể
đóng hộp thoại theo cách thủ công bằng cách gọi
dismiss()
trên DialogFragment
của bạn.
Nếu cần thực hiện một số thao tác khi hộp thoại biến mất, bạn có thể
triển khai
onDismiss()
trong DialogFragment
của bạn.
Bạn cũng có thể huỷ hộp thoại. Đây là một sự kiện đặc biệt
chỉ ra rằng người dùng đang rời khỏi hộp thoại khi chưa hoàn tất tác vụ. Chiến dịch này
xảy ra nếu người dùng nhấn vào nút Quay lại hoặc nhấn vào màn hình bên ngoài hộp thoại
hoặc nếu bạn gọi rõ ràng
cancel()
trên Dialog
, chẳng hạn như để phản hồi yêu cầu "Huỷ" nút trong
.
Như trong ví dụ trước, bạn có thể phản hồi sự kiện huỷ bằng cách
triển khai
onCancel()
trong lớp DialogFragment
của bạn.