使用 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() 應如何在一般片段中建立跟層級 ViewonCreateDialog() 應建立一個可顯示為的 DialogFragment一部分的 DialogDialogFragment 控制在片段的生命週期中以適當狀態顯示 Dialog

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

顯示 DialogFragment

不必手動建立 FragmentTransaction 來顯示您的 DialogFragment。請改用 show() 方法顯示您的對話方塊。您可以將參照傳遞至 FragmentManagerString,作為 FragmentTransaction 標記使用。從 Fragment 中建立 DialogFragment 時,請務必使用 Fragment 的子項 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 遵循標準片段的生命週期。此外,DialogFragment 還有幾個其他的生命週期回呼。最常見的幾個如下:

  • onCreateDialog() - 覆寫這個回呼,提供一個 Dialog,獲得可管理和顯示的片段。
  • onDismiss() - 如果關閉 Dialog 時需要執行任何自訂邏輯 (例如,釋出資源、從可觀測資源取消訂閱等),請覆寫這個回呼,依此類推。
  • onCancel() - 如要取消 Dialog 時需要執行任何自訂邏輯,請覆寫這個回呼。

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

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

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

使用自訂檢視畫面

您可以建立 DialogFragment,並覆寫 onCreateView(),像處理典型片段一般提供 layoutId,或使用 DialogFragment 建構函式,即可顯示對話方塊。

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

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