使用 DialogFragment 顯示對話方塊

DialogFragment 是一種特殊片段的子類別,專為建立及代管 對話方塊 而設計。雖然您不需要在片段中代管對話方塊,但這麼做可讓 FragmentManager 管理對話方塊的狀態,並自動還原發生設定變更時顯示的對話方塊。

建立 DialogFragment

如要建立 DialogFragment,請先建立可擴充 DialogFragment 和覆寫 onCreateDialog() 的類別,如以下範例所示。

Kotlin

class PurchaseConfirmationDialogFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
            AlertDialog.Builder(requireContext())
                .setMessage(getString(R.string.order_confirmation))
                .setPositiveButton(getString(R.string.ok)) { _,_ -> }
                .create()

    companion object {
        const val TAG = "PurchaseConfirmationDialog"
    }
}

Java

public class PurchaseConfirmationDialogFragment extends DialogFragment {
   @NonNull
   @Override
   public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
       return new AlertDialog.Builder(requireContext())
               .setMessage(getString(R.string.order_confirmation))
               .setPositiveButton(getString(R.string.ok), (dialog, which) -> {} )
               .create();
   }

   public static String TAG = "PurchaseConfirmationDialog";
}

就像 onCreateView() 在一般片段中建立根 View 一樣,onCreateDialog() 會建立 Dialog,做為 DialogFragment 的一部分顯示。DialogFragment 控制在片段的生命週期中以適當狀態顯示 Dialog

onCreateView() 一樣,您可以從 onCreateDialog() 傳回 Dialog 的任何子類別,而且不限於使用 AlertDialog

顯示 DialogFragment

您可以不必手動建立 FragmentTransaction 來顯示 DialogFragment,請改用 show() 方法顯示您的對話方塊。您可以將參照傳遞至 FragmentManagerString,做為 FragmentTransaction 標記使用。

Fragment 中建立 DialogFragment 時,請使用片段的子項 FragmentManager,即可讓狀態在設定變更後正確還原。非空值的標記讓您可在過一段時間後,使用 findFragmentByTag() 擷取 DialogFragment

Kotlin

// From another Fragment or Activity where you wish to show this
// PurchaseConfirmationDialogFragment.
PurchaseConfirmationDialogFragment().show(
     childFragmentManager, PurchaseConfirmationDialog.TAG)

Java

// From another Fragment or Activity where you wish to show this
// PurchaseConfirmationDialogFragment.
new PurchaseConfirmationDialogFragment().show(
       getChildFragmentManager(), PurchaseConfirmationDialog.TAG);

如要進一步控管 FragmentTransaction,可以使用接受現有 FragmentTransactionshow() 超載。

DialogFragment 生命週期

DialogFragment 遵循標準片段的生命週期,還有一些額外的生命週期回呼。最常見的幾個如下:

  • onCreateDialog():覆寫這個回呼以提供 Dialog,以便管理和顯示片段。
  • onDismiss():如果關閉 Dialog 時需要執行任何自訂邏輯 (例如釋出資源或從可觀測資源取消訂閱),請覆寫這個回呼。
  • onCancel():如果取消 Dialog 時需要執行任何自訂邏輯,請覆寫這個回呼。

DialogFragment 也包含關閉或設定 DialogFragment 可取消性的方法:

  • dismiss():關閉片段及其對話方塊。如果將片段新增至返回堆疊,則系統會彈出所有返回堆疊狀態,包括這個項目在內。否則,系統會指定新的交易用於移除片段。
  • setCancelable():控制是否可取消已顯示的 Dialog。請使用這個方法,不要直接呼叫 Dialog.setCancelable(boolean)

DialogFragment 搭配 Dialog 使用時,系統不會覆寫 onCreateView()onViewCreated()。對話方塊並非只是檢視畫面,也擁有自己的視窗,因此不足以覆寫 onCreateView()。此外,除非您覆寫了 onCreateView() 並提供非空值的檢視畫面,否則系統一律不會在自訂的 DialogFragment 上呼叫 onViewCreated()

使用自訂檢視畫面

您可以藉由覆寫 onCreateView() 來建立 DialogFragment 並顯示對話方塊。您可以和一般片段一樣為其提供 layoutId,或使用 DialogFragment 建構函式

onCreateView() 傳回的 View 會自動新增至對話方塊。在大多數情況下,這表示您不需要覆寫 onCreateDialog(),因為系統會將預設的空白對話方塊填入您的檢視畫面。

某些 DialogFragment 的子類別 (例如 BottomSheetDialogFragment) 會在設計成底部功能表樣式的對話方塊中嵌入檢視畫面。