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() 在普通片段中创建根 View 类似,onCreateDialog() 创建一个 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,您可以使用接受现有 FragmentTransaction 的 show() 重载方法。
DialogFragment 生命周期
A DialogFragment 遵循标准片段生命周期,并具有一些额外的生命周期回调。最常见的如下所示:
onCreateDialog():覆盖此回调以提供一个Dialog,供片段管理和显示。onDismiss():如果您需要在Dialog关闭时执行任何自定义逻辑,例如释放资源或取消订阅可观察资源,请覆盖此回调。onCancel():如果您需要在Dialog取消时执行任何自定义逻辑,请覆盖此回调。
DialogFragment 还包含用于关闭或设置 DialogFragment 可取消性的方法
dismiss():关闭片段及其对话框。如果片段已添加到返回栈,则返回栈中直至(包括)此条目之前的所有状态都将弹出。否则,将提交新的事务以移除片段。setCancelable():控制显示的Dialog是否可取消。使用此方法而不是直接调用Dialog.setCancelable(boolean)。
当使用带有 Dialog 的 DialogFragment 时,您不会覆盖 onCreateView() 或 onViewCreated()。对话框不仅仅是视图——它们有自己的窗口。因此,仅仅覆盖 onCreateView() 是不够的。此外,除非您已覆盖 onCreateView() 并提供了非空视图,否则 onViewCreated() 永远不会在自定义 DialogFragment 上调用。
使用自定义视图
您可以创建一个 DialogFragment 并通过覆盖 onCreateView() 来显示对话框。您可以像典型的片段一样为其指定一个 layoutId,或者使用 DialogFragment 构造函数。
由 onCreateView() 返回的 View 会自动添加到对话框中。在大多数情况下,这意味着您不需要覆盖 onCreateDialog(),因为默认的空对话框会填充您的视图。
某些 DialogFragment 的子类,例如 BottomSheetDialogFragment,会将您的视图嵌入到样式为底部工作表的对话框中。