使用 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,以便在配置更改后状态能够正确恢复。非空标签允许您使用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()并提供了一个非空视图,否则自定义DialogFragment上永远不会调用onViewCreated()

使用自定义视图

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

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

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