使用 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) 會在對話方塊中嵌入檢視畫面。