使用导航组件时关闭 DialogFragment 的正确方法? [英] Correct way to close DialogFragment when using Navigation component?

查看:55
本文介绍了使用导航组件时关闭 DialogFragment 的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using the Navigation component to show a DialogFragment (<dialog...>...</dialog> in the navigation.xml) and want to know what's the recommended way to close the Dialog. I tried myself and got the following results:

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

1) dismiss()in DialogFragment: seems to work fine

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

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

3) findNavController().navigate(MyDialogFragmentDirections.actionMyDialogFragmentToMyNormalFragment()): works, but loads a fresh version of the target destination, so depending on the use case this might not be what one wants to have.

注意:我的用例是 MyNormalFragment 使用 MyDialogFragment 来获取一些输入,所以在显示 MyDialogFragment 之后,我需要返回到现有的 MyNormalFragment 实例.

Note: My use case is that MyNormalFragmentuses MyDialogFragmentto get some input, so after MyDialogFragmentis shown, I need to get back to the already existing instance of MyNormalFragment.

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

So for me, only 1) or 2) is correct. Now I am wondering, is there any difference between 1) and 2) ?

推荐答案

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

Both 1) and 2) end up doing the same thing the end, but 2) is always a safer option.

当你调用 dismiss() 时,DialogFragment 被解除并且 DialogFragment 被停止(它接收到 onStop 的回调()).这会触发 DialogFragmentNavigator 中的监听器,然后通过调用 更新 NavController 的状态>popBackStack().

When you call dismiss(), the DialogFragment is dismissed and the DialogFragment is stopped (it receives a callback to onStop()). This triggers the listener in DialogFragmentNavigator, which then updates the NavController's state by calling popBackStack().

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

dismiss() however, is an asynchronous operation (as seen in the DialogFragment source code - you'll note it does not use commitNow(), etc). Therefore if you were to check what destination you are on from the NavController.getCurrentDestination(), you'd see that you're still on the dialog destination, despite having triggered the dismissal.

navigateUp() 直接进入 NavController.由于您的后台堆栈上有另一个目的地(DialogFragment 下的那个),因此 NavController源代码表明 navigateUp() 只是调用 popBackStack() - dismiss() 最终触发的操作相同.

navigateUp(), on the other hand, goes directly to the NavController. Since you have another destination on your back stack (the one under the DialogFragment), the NavController source code shows that navigateUp() just calls popBackStack() - the same operation that dismiss() was eventually triggering.

但是,当驱动操作的是 NavController 时,NavController 会同步更新其状态.这意味着在您调用 navigateUp() 之后,除了调用 DialogFragmentNavigatorpopBackStack(),这是调用 dismiss() 的方法(移除观察者上面提到的以防止双重解雇).

However, when it is the NavController that is driving the operation, NavController updates its state synchronously. This means that immediately after you call navigateUp(), it will have updated its getCurrentDestination() and internal state in addition to calling through to DialogFragmentNavigator's popBackStack(), which is what calls through to dismiss() (removing the observer mentioned above to prevent double dismissals).

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

Therefore calling navigateUp() is always the safer choice since it ensures that the NavController is synchronously updated to the correct state, rather than rely on FragmentManager's asynchronous timing (which may mean that additional click events are received during that time period due to multi-touch, etc.).

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

Calling navigate() with an action that has an app:destination on it will navigate to a new instance of the destination, which would not be appropriate for returning back to your previous instance.

这篇关于使用导航组件时关闭 DialogFragment 的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆