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

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

问题描述

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

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()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()的回调).这会触发

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()是异步操作(如

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下的目标),因此

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()之后,除了通过调用

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天全站免登陆