使用 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() 创建一个 Dialog 以显示为 DialogFragment 的一部分。 DialogFragment 处理在片段生命周期的适当状态下显示 Dialog

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

显示 DialogFragment

您不必手动创建 FragmentTransaction 来显示 DialogFragment。相反,请使用 show() 方法显示对话框。您可以传递对 FragmentManager 的引用和一个用作 FragmentTransaction 标签的 String

在从 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 遵循标准的 Fragment 生命周期,但也包含一些额外的生命周期回调。最常见的回调如下:

  • onCreateDialog():重写此回调方法,为 Fragment 提供一个要管理和显示的 Dialog
  • onDismiss():如果需要在 Dialog 关闭时执行任何自定义逻辑,例如释放资源或取消订阅可观察资源,请重写此回调方法。
  • onCancel():如果需要在 Dialog 被取消时执行任何自定义逻辑,请重写此回调方法。

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

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

使用 DialogFragmentDialog 时,您不需要重写 onCreateView()onViewCreated()。对话框不仅仅是视图,它们还有自己的窗口。因此,仅仅重写 onCreateView() 并不足以满足要求。此外,除非您已重写 onCreateView() 并提供了非空视图,否则 onViewCreated() 永远不会在自定义的 DialogFragment 上被调用。

使用自定义视图

您可以创建一个 DialogFragment 并通过重写 onCreateView() 来显示一个对话框。您可以像在典型的 Fragment 中一样提供一个 layoutId,或者使用 DialogFragment 构造函数

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

某些 DialogFragment 的子类,例如 BottomSheetDialogFragment,会将您的视图嵌入到一个样式为底部菜单的对话框中。