【问题标题】:Correct way to close DialogFragment when using Navigation component?使用导航组件时关闭 DialogFragment 的正确方法?
【发布时间】:2020-04-04 21:30:04
【问题描述】:

我正在使用导航组件显示DialogFragmentnavigation.xml 中的<dialog...>...</dialog>)并想知道关闭对话框的推荐方法是什么。我自己试了一下,结果如下:

1) dismiss()in DialogFragment: 似乎工作正常

2) findNavController().navigateUp(): 似乎工作正常

3) findNavController().navigate(MyDialogFragmentDirections.actionMyDialogFragmentToMyNormalFragment()):有效,但会加载目标目的地的新版本,因此根据用例,这可能不是人们想要的。

注意:我的用例是MyNormalFragment使用MyDialogFragment来获取一些输入,所以在显示MyDialogFragment之后,我需要回到已经存在的MyNormalFragment实例。

所以对我来说,只有 1) 或 2) 是正确的。现在我想知道,1)和2)之间有什么区别吗?

【问题讨论】:

    标签: android navigation android-architecture-components


    【解决方案1】:

    1) 和 2) 最终都会做同样的事情,但 2) 始终是更安全的选择。

    当您调用dismiss() 时,DialogFragment 被解除,DialogFragment 被停止(它接收到onStop() 的回调)。这会触发listener in DialogFragmentNavigator,然后通过调用popBackStack() 来更新NavController 的状态。

    dismiss() 然而,是一个异步操作(如在DialogFragment source code 中看到的 - 你会注意到它不使用commitNow() 等)。因此,如果您要从 NavController.getCurrentDestination() 检查您所在的目的地,您会看到您仍在对话目的地上,尽管已触发解雇。

    另一方面,navigateUp() 直接进入 NavController。由于您的后台堆栈上有另一个目的地(DialogFragment 下的那个),NavController source code 表明 navigateUp() 只是调用 popBackStack() - 与 dismiss() 最终触发的操作相同。

    但是,当驱动操作的是NavController 时,NavController 会同步更新其状态。这意味着,在您调用navigateUp() 之后,它会立即更新其getCurrentDestination() 和内部状态,以及调用DialogFragmentNavigator's popBackStack(),这就是调用dismiss()(删除上面提到的观察者以防止双重解雇)。

    因此调用navigateUp() 始终是更安全的选择,因为它确保NavController 同步更新到正确的状态,而不是依赖FragmentManager 的异步计时(这可能意味着接收到额外的点击事件在那个时间段内由于多点触控等)。

    使用带有app:destination 的操作调用navigate() 将导航到目的地的新实例,这不适合返回到之前的实例。

    【讨论】:

    • 对我来说,dismiss 不起作用,navhostfragment 的当前目的地没有更新。我想知道我的对话框片段是否从导航图启动并且基于某些条件没有导航图,那么我可以调用 findNavController().navigateUp() 吗?
    • @Himanshu 我有同样的问题,很难工作。
    • 因此,如果我有一个取消和保存按钮,并且即使在对话框外触摸时也会关闭,我应该在哪里调用 navigateUp?我现在的问题是这些操作中的任何一个都会删除我工具栏上的后退按钮。
    • @Chucky - 假设您的取消和保存按钮来自AlertDialog,那么这些按钮已经在内部关闭了对话框,就像在对话框外点击一样。 Navigation 仍会监听这些事件并为您更新 Navigation 状态。如果您将navigate() 作为取消/保存按钮的一部分,我会确保该操作也会弹出对话框(即使用popUpTo) - 这将确保在您导航之前首先记录对话框弹出去一个新的目的地。
    • 谢谢汉尼拔。我怀疑这是已经处理的情况。但我仍然不确定为什么关闭让我在下面的片段上的后退按钮消失了?
    猜你喜欢
    • 2012-03-08
    • 2012-06-27
    • 1970-01-01
    • 2012-07-04
    • 2018-12-22
    • 2020-08-21
    • 2014-05-02
    • 2016-09-02
    • 2013-06-27
    相关资源
    最近更新 更多