page.title=Hộp thoại page.tags=alertdialog,dialogfragment @jd:body

Trong tài liệu này

  1. Tạo một Phân đoạn Hộp thoại
  2. Xây dựng một Hộp thoại Cảnh báo
    1. Thêm nút
    2. Thêm một danh sách
    3. Tạo một Bố trí Tùy chỉnh
  3. Chuyển Sự kiện lại Máy chủ của Hộp thoại
  4. Hiển thị một Hộp thoại
  5. 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
    1. 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
  6. Bỏ một Hộp thoại

Lớp khóa

  1. {@link android.app.DialogFragment}
  2. {@link android.app.AlertDialog}

Xem thêm

  1. Hướng dẫn thiết kế hộp thoại
  2. Bộ chọn (Hộp thoại Ngày/Giờ)

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.

Thiết kế Hộp thoại

Để 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ế Hộp thoại.

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:

{@link android.app.AlertDialog}
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.
{@link android.app.DatePickerDialog} hoặc {@link android.app.TimePickerDialog}
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ờ.

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}.

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 Quay lại 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ỏ).

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 Bộ chọn.

Lưu ý: 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 Thư viện Hỗ trợ. 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 android.support.v4.app.DialogFragment chứ không phải android.app.DialogFragment.

Tạo một Phân đoạn Hộp thoại

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ế Hộp thoại —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()}.

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}:

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();
    }
}

Hình 1. Hộp thoại với một thông báo và hai nút hành động.

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.

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.

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ả phương pháp vòng đời phân đoạn cơ bản.

Xây dựng một Hộp thoại Cảnh báo

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:

Hình 2. Bố trí của một hộp thoại.

  1. Tiêu đề

    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 đề.

  2. Vùng nội dung

    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.

  3. Nút hành động

    Sẽ không có quá ba nút hành động trong một hộp thoại.

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.

Để xây dựng một {@link android.app.AlertDialog}:

// 1. Instantiate an {@link android.app.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 {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}
AlertDialog dialog = builder.create();

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}.

Thêm nút

Để 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()}:

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();

Các phương pháp set...Button() yêu cầu một tiêu đề cho nút (được cung cấp bởi một tài nguyên xâu) 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.

Có ba nút hành động khác nhau mà bạn có thể thêm:

Tích cực
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").
Tiêu cực
Bạn nên sử dụng nút này để hủy bỏ hành động.
Trung lập
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."

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".

Hình 3. Hộp thoại có tiêu đề và danh sách.

Thêm một danh sách

Có ba loại danh sách có sẵn với các API {@link android.app.AlertDialog}:

Để 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()}:

@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();
}

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}.

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 Xây dựng Bố trí bằng một Trình điều hợpTrình tải .

Lưu ý: 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.

Hình 4. Danh sách nhiều mục lựa chọn.

Thêm một danh sách nhiều lựa chọn hoặc một lựa chọn cố định

Để 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.

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}:

@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();
}

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.

Tạo một Bố trí Tùy chỉnh

Hình 5. Một bố trí hộp thoại tùy chỉnh.

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.

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 đề.

Ví dụ, sau đây là tệp bố trí cho hộp thoại trong Hình 5:

res/layout/dialog_signin.xml

<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>

Mẹo: 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.

Để 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.

@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();
}

Mẹo: 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 {@code <activity>}:

<activity android:theme="@android:style/Theme.Holo.Dialog" >

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.

Chuyển Sự kiện lại Máy chủ của Hộp thoại

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.

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ủ:

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");
        }
    }
    ...
}

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}:

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
        ...
    }
}

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:

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();
    }
}

Hiển thị một Hộp thoại

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.

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ụ:

public void confirmFireMissiles() {
    DialogFragment newFragment = new FireMissilesDialogFragment();
    newFragment.show(getSupportFragmentManager(), "missiles");
}

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()}.

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

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.

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()}.

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 purchase_items.xml):

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;
    }
}

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:

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();
    }
}

Để 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 Phân đoạn.

Trong ví dụ này, boolean mIsLargeLayout 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 giá trị tài nguyên bool bằng một giá trị tài nguyên thay thế 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:

res/values/bools.xml

<!-- Default boolean values -->
<resources>
    <bool name="large_layout">false</bool>
</resources>

res/values-large/bools.xml

<!-- Large screen boolean values -->
<resources>
    <bool name="large_layout">true</bool>
</resources>

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:

boolean mIsLargeLayout;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
}

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

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.

Để 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 {@code <activity>}:

<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" >

Để 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 Kiểu và Chủ đề.

Bỏ một Hộp thoại

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.

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.

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.

Bạn cũng có thể hủy bỏ 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 Quay lại, 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).

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.

Lưu ý: 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()} chứ không phải {@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 tích cực trong hộp thoại của bạn để xóa hộp thoại khỏi dạng xem.