使用 DialogFragment 显示对话框

DialogFragment 是一个专用于创建和托管对话框的特殊 fragment 子类。尽管您无需在 fragment 中托管对话框,但如果托管,便可以在发生配置更改时允许 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() 在普通 fragment 中创建根 View 的方式相类似,onCreateDialog() 会创建 Dialog 作为 DialogFragment 的一部分显示。DialogFragment 句柄在 fragment 的生命周期中以适当的状态显示 Dialog。

与 onCreateView() 一样,您可以从 onCreateDialog() 返回 Dialog 的任何子类,并且不限于使用 AlertDialog。

显示 DialogFragment

您不必手动创建 FragmentTransaction 来显示 DialogFragment,而是使用 show() 方法显示您的对话框。您可以传递对 FragmentManager 和 String 的引用,将其用作 FragmentTransaction 标记。

从 Fragment 内创建 DialogFragment 时,请使用 fragment 的子 FragmentManager,以便在配置更改后状态可以正确恢复。非 null 标记让您可以使用 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,您可以使用接受现有 FragmentTransaction 的 show() 过载。

DialogFragment 生命周期

DialogFragment 遵循标准 fragment 生命周期,还有几个额外的生命周期回调。最常见的如下所示:

  • onCreateDialog():替换此回调以提供 Dialog,以便管理和显示 fragment。
  • onDismiss():如果您需要在 Dialog 关闭时执行任何自定义逻辑(例如释放资源或退订可观察资源),请替换此回调。
  • onCancel():如果您需要在 Dialog 取消时执行任何自定义逻辑,请替换此回调。

DialogFragment 还包含用于关闭或设置 DialogFragment 的可取消性的方法:

  • dismiss():关闭 fragment 及其对话框。如果 fragment 已添加到返回堆栈,会弹出所有返回堆栈状态(包括此条目)。 否则,会提交新事务以移除 fragment。
  • setCancelable():控制所显示的 Dialog 是否可取消。请使用此方法,而不是直接调用 Dialog.setCancelable(boolean)。

在使用具有 Dialog 的 DialogFragment 时,您不能替换 onCreateView() 或 onViewCreated()。对话框不仅仅是视图,它们有自己的窗口。因此,替换 onCreateView() 还不够。此外,除非您替换了 onCreateView() 并提供非 null 视图,否则绝不会对自定义 DialogFragment 调用 onViewCreated()。

使用自定义视图

您可以通过替换 onCreateView() 来创建 DialogFragment 并显示对话框。 您可以赋予其 layoutId(与处理典型 fragment 的方式相同)或使用 DialogFragment 构造函数。

由 onCreateView() 返回的 View 会自动添加到对话框中。在大多数情况下,这意味着您不需要替换 onCreateDialog(),因为默认的空对话框将填入您的视图。

DialogFragment 的某些子类(例如 BottomSheetDialogFragment)将视图嵌入在底部工作表样式的对话框中。