使用 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() 方法显示您的对话框。您可以传递对 FragmentManagerString 的引用,将其用作 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,您可以使用接受现有 FragmentTransactionshow() 过载。

DialogFragment 生命周期

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

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

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

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

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

使用自定义视图

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

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

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