使用 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() 方法顯示對話方塊。您可以將參照傳遞至 FragmentManager,並傳遞 String 做為 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()

使用自訂檢視畫面

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

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

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