导航 DESTINATION_NAME 对此 NavController 未知,重新打开之前使用 navController.popBackStack() 关闭的片段?
Navigation DESTINATION_NAME is unknown to this NavController, ReOpening fragment previously closed using navController.popBackStack()?
我在我的应用程序中使用导航组件,最近它工作正常但是在将项目更新到 AndroidX
之后我收到错误 navigation destination DESTINATION_NAME is unknown to this NavController
只有当那个目的地(我'm going to open) 之前使用 navController.popBackStack()
从自身关闭。此外,如果我从 MainActivity
关闭 DESTINATION 片段也没有错误,但仅发生错误片段是使用 popBackStack
从自身关闭的。像下面
DestinationFragment
viewModelOfActivity.handleBackButton.observe(this, Observer {
Navigation.findNavController(requireActivity(), R.id.main_nav_host).popBackStack()
//CALLING popBackStack() HERE CAUSING PROBLEM WHEN REOPNING THIS DESTINATION(or frg ) AGIAN
})
MainActivity
override fun onBackPressed() {
if (myViewModel.isDefaultBehaviour.value == true) {
super.onBackPressed()
} else{
myViewModel.handleBackButton.value=true
//NO ERROR IF HANDLE BACK BUTTON HERE ie->findNavController(R.id.main_nav_host).popBackStack()
//INSTEAD OF myViewModel.handleBackButton
}
}
我也检查了相关问题,但没有帮助 Similar Question。
注意:我使用的是最新版本的导航库 (alpha05)
之前的值可能仍然存在于视图模型中并立即触发。我建议使用一个接口来处理您的后退按钮委托,而不是观察者。那应该修复用法。
发生的事情是您在返回堆栈中弹出太多,以至于您不再有活动图表。发生这种情况是因为您的观察者比应有的更频繁地被触发。要看到这一点,我建议在崩溃之前调试该行并检查图表。很可能为空。
我在 DestinationFragment 中使用 SingleLiveEvent 来观察来自 MainActivity 的返回压力,因为我已经在我的问题中提到了这一点.所以问题出在 SingleLiveEvent
我注意到我不小心将 fun observe(owner: LifecycleOwner, observer: Observer<in T>)
的代码更改为
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, observer)//Here is problem I was calling super twice in function
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
super.observe(owner, Observer { t ->/** other code*//})
}
在这里你可以看到我调用了两次 super
函数,在 Fragment
中两次调用了观察者的 onChanged
,下面的代码被调用了两次
Navigation.findNavController(requireActivity(), R.id.main_nav_host).popBackStack()
popBackStack()
两次。
然后我更改了 observe
函数,如下所示
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
super.observe(owner, Observer { t ->/** other code*//})
}
现在我的代码可以正常工作了
我遇到了同样的问题。在我的应用程序中有三个片段 A -> B -> C
,我不得不从 C
return 到 A
。在我的例子中,我使用 popBackStack()
关闭当前片段,并使用 return 关闭前一个片段,之后任何从 A
导航的尝试都会抛出 Navigation xxx is unknown to this NavController
异常。
我最终使用 navigate()
到 A
而不是从返回堆栈中弹出片段。使用 popUpTo
和 popUpToInclusive
设置正确解决了这个问题(参见文档 https://developer.android.com/guide/navigation/navigation-getting-started#popupto_example_circular_logic)
<fragment
android:id="@+id/FragmentC"
android:name="xxx.FragmentC"
android:label="C" >
<action
android:id="@+id/action_to_A"
app:destination="@id/FragmentA"
app:popUpTo="@+id/FragmentA"
app:popUpToInclusive="true" />
</fragment>
我就是这样用的
@Override
public void onBackPressed() {
if(myNavController.getCurrentDestination().getId()==R.id.startDestinationId)
/** do something */
else myNavController.popBackStack();
}
我在我的应用程序中使用导航组件,最近它工作正常但是在将项目更新到 AndroidX
之后我收到错误 navigation destination DESTINATION_NAME is unknown to this NavController
只有当那个目的地(我'm going to open) 之前使用 navController.popBackStack()
从自身关闭。此外,如果我从 MainActivity
关闭 DESTINATION 片段也没有错误,但仅发生错误片段是使用 popBackStack
从自身关闭的。像下面
DestinationFragment
viewModelOfActivity.handleBackButton.observe(this, Observer {
Navigation.findNavController(requireActivity(), R.id.main_nav_host).popBackStack()
//CALLING popBackStack() HERE CAUSING PROBLEM WHEN REOPNING THIS DESTINATION(or frg ) AGIAN
})
MainActivity
override fun onBackPressed() {
if (myViewModel.isDefaultBehaviour.value == true) {
super.onBackPressed()
} else{
myViewModel.handleBackButton.value=true
//NO ERROR IF HANDLE BACK BUTTON HERE ie->findNavController(R.id.main_nav_host).popBackStack()
//INSTEAD OF myViewModel.handleBackButton
}
}
我也检查了相关问题,但没有帮助 Similar Question。
注意:我使用的是最新版本的导航库 (alpha05)
之前的值可能仍然存在于视图模型中并立即触发。我建议使用一个接口来处理您的后退按钮委托,而不是观察者。那应该修复用法。
发生的事情是您在返回堆栈中弹出太多,以至于您不再有活动图表。发生这种情况是因为您的观察者比应有的更频繁地被触发。要看到这一点,我建议在崩溃之前调试该行并检查图表。很可能为空。
我在 DestinationFragment 中使用 SingleLiveEvent 来观察来自 MainActivity 的返回压力,因为我已经在我的问题中提到了这一点.所以问题出在 SingleLiveEvent
我注意到我不小心将 fun observe(owner: LifecycleOwner, observer: Observer<in T>)
的代码更改为
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, observer)//Here is problem I was calling super twice in function
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
super.observe(owner, Observer { t ->/** other code*//})
}
在这里你可以看到我调用了两次 super
函数,在 Fragment
中两次调用了观察者的 onChanged
,下面的代码被调用了两次
Navigation.findNavController(requireActivity(), R.id.main_nav_host).popBackStack()
popBackStack()
两次。
然后我更改了 observe
函数,如下所示
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
super.observe(owner, Observer { t ->/** other code*//})
}
现在我的代码可以正常工作了
我遇到了同样的问题。在我的应用程序中有三个片段 A -> B -> C
,我不得不从 C
return 到 A
。在我的例子中,我使用 popBackStack()
关闭当前片段,并使用 return 关闭前一个片段,之后任何从 A
导航的尝试都会抛出 Navigation xxx is unknown to this NavController
异常。
我最终使用 navigate()
到 A
而不是从返回堆栈中弹出片段。使用 popUpTo
和 popUpToInclusive
设置正确解决了这个问题(参见文档 https://developer.android.com/guide/navigation/navigation-getting-started#popupto_example_circular_logic)
<fragment
android:id="@+id/FragmentC"
android:name="xxx.FragmentC"
android:label="C" >
<action
android:id="@+id/action_to_A"
app:destination="@id/FragmentA"
app:popUpTo="@+id/FragmentA"
app:popUpToInclusive="true" />
</fragment>
我就是这样用的
@Override
public void onBackPressed() {
if(myNavController.getCurrentDestination().getId()==R.id.startDestinationId)
/** do something */
else myNavController.popBackStack();
}