到目前为止,我已经成功地导航到对话框并仅使用导航组件返回。问题是,我必须在对话框中做一些事情,并将结果返回到调用对话框的片段。
一种方法是使用共享viewmodel。但我必须使用。(活动)这让我的应用程序占用了一个单独的内存,即使我不再需要它。
另一种方法是覆盖show(framentManager, id)方法,访问片段管理器并从中访问先前的片段,然后将其设置为目标片段。我以前使用过目标片段方法,我将实现回调接口,因此我的对话框可以通知目标片段结果。但是在导航组件方法中,它感觉很古怪,可能会在某个时候停止工作。
还有其他方法可以做我想做的吗?也许有一种方法可以解决第一种方法的问题?
当您在对话框中使用导航组件时,这部分代码看起来不太好(对我来说,它没有返回任何内容)
navController.currentBackStackEntry?.savedStateHandle?.getLiveData("key")?.observe(
viewLifecycleOwner) { result ->
// Do something with the result.}
你们需要从官方文件中试试,这对我有很大帮助
这一部分对我有用:
val navBackStackEntry = navController.getBackStackEntry(R.id.target_fragment_id)
// Create observer and add it to the NavBackStackEntry's lifecycle
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME
&& navBackStackEntry.savedStateHandle.contains("key")
) {
val result =
navBackStackEntry.savedStateHandle.get<Boolean>("key")
// Do something with the result
}
}
navBackStackEntry.lifecycle.addObserver(observer)
// As addObserver() does not automatically remove the observer, we
// call removeObserver() manually when the view lifecycle is destroyed
viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_DESTROY) {
navBackStackEntry.lifecycle.removeObserver(observer)
}
})
在您的对话框中:
navController.previousBackStackEntry?.savedStateHandle?.set(
"key",
true
)
多亏了@NataTse和官方文档,我提出了扩展,希望可以编写更少的样板代码:
fun <T>Fragment.setNavigationResult(key: String, value: T) {
findNavController().previousBackStackEntry?.savedStateHandle?.set(
key,
value
)
}
fun <T>Fragment.getNavigationResult(@IdRes id: Int, key: String, onResult: (result: T) -> Unit) {
val navBackStackEntry = findNavController().getBackStackEntry(id)
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME
&& navBackStackEntry.savedStateHandle.contains(key)
) {
val result = navBackStackEntry.savedStateHandle.get<T>(key)
result?.let(onResult)
navBackStackEntry.savedStateHandle.remove<T>(key)
}
}
navBackStackEntry.lifecycle.addObserver(observer)
viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_DESTROY) {
navBackStackEntry.lifecycle.removeObserver(observer)
}
})
}
在Navigation 2.3.0-alpha02及更高版本中,NavBackbackEntry提供了对SavedStateHandle的访问。SavedStateHandle是一个键值映射,可用于存储和检索数据。这些值在进程死亡(包括配置更改)期间持续存在,并在同一对象中保持可用。通过使用给定的SavedStateHandle,您可以在目标之间访问和传递数据。作为一种机制,当数据从堆栈中弹出后,它特别有用,可以从目标中获取数据。
要将数据从目的地B传递回目的地A,首先设置目的地A以侦听其SavedStateHandle上的结果。为此,请使用getCurrentBackStackEntry()API检索NavBackStackEntry,然后观察SavedStateHandle提供的LiveData。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val navController = findNavController();
// We use a String here, but any type that can be put in a Bundle is supported
navController.currentBackStackEntry?.savedStateHandle?.getLiveData("key")?.observe(
viewLifecycleOwner) { result ->
// Do something with the result.
}
}
在目标B中,您必须使用getPreviousBackStackEntry()API在目标A的SavedStateHandle上设置结果。
navController.previousBackStackEntry?.savedStateHandle?.set("key", result)
是否可以将新的导航架构组件与DialogFragment一起使用?我必须创建自定义导航器吗? 我很乐意将它们与导航图中的新功能结合使用。
我使用childFragmentManager在片段内显示一个对话框,或者使用supportFragmentManager在活动内显示一个对话框,在这个过程中,我想设置目标片段,如下所示: 但在运行该代码时,我得到了一个错误: java.lang.非法状态异常:片段文本搜索对话片段{b7fce67#0 0}声明不属于此FragmentManager的目标片段PlaceSearch片段{f87414
问题内容: 我有一个线程,每隔六秒钟将GPS坐标发送到数据库,并且有一个检查可以验证用户是否在定义的区域内。如果用户不在该位置内,则我需要一个警报对话框,通知他们它们不在范围内;如果用户在该区域内,我想要一个对话框,告诉他们它们在范围内。我的检查工作正常,但是我已经尝试过了,而且我很确定我不能在后台线程上添加对话框。我已经读过一些有关使用处理程序的信息,但是我不确定如何实现。如果您有任何建议,我将
导航组件说明 组件 说明 最低版本 navigator 页面链接 1.0.0 functional-page-navigator 用于跳转插件功能页 不支持 navigator 属性 类型 默认值 必填 说明 最低版本 url string 否 当前小程序内的跳转链接 open-type navigate 否 跳转方式 hover-class string navigator-hover 否 指定
我正在一个新的Android应用程序上使用导航组件,但我不知道怎么做 首先,我有我的主活动,我有main_navigation_graph 主要活动 NavHostFragment main_navigation_graph里面有3个碎片 这里一切都很好。问题是当我到达最后一个片段时,因为在这个片段上,我想根据BottomNavigationView输入(暂时)显示一些子片段(在新的NavHost
这个对话框包含用 查找文件 命令找到的条目。您可以选择一个或一个以上的文件然后选择“解压缩到”来解压它们。您也可以按下“查看”来查看光标所在处的文件或者是“定位”来在 WinRAR 的主窗口中选定这个文件。 因为技术限制,如果搜索时执行查找到的文件会有一定的延迟。 WinRAR 只有在当前正在处理的压缩文件已经被关闭时才执行这个命令。