导航目的地DESTINATION_NAME在此NavController中未知,是否重新打开以前使用navController.popBackStack()关闭的片段?

11

我正在使用导航组件来开发我的应用,在更新项目到 AndroidX 后,当我从目标页面中使用 navController.popBackStack() 关闭页面时,如果该目标页面之前被关闭过,就会出现错误 navigation destination DESTINATION_NAME is unknown to this NavController。但是如果我从 MainActivity 关闭 DESTINATION 页面,则不会出现错误。只有在使用 popBackStack 从页面本身关闭 DESTINATION 页面时才会出现错误。

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
    }
}

我已经查看了相关的问题,但没有获得帮助。类似问题

注意:我正在使用最新版本的导航库(alpha05)。

4个回答

0

我之前在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*//})
}  

现在我的代码运行良好


0

之前的值很可能仍然存在于视图模型中并立即触发。我建议使用接口来处理后退按钮委托,而不是使用观察者。这应该可以解决问题。

发生的情况是您弹出了太多的后退堆栈,以至于您不再有活动图形。这是因为您的观察者被触发的频率比应该触发的频率更高。为了查看这一点,我建议调试该行并在崩溃之前检查图形。它很可能为空。


我正在使用SingleLiveEvent,它只会触发一次。 - Kulwinder Singh Rahal

0

我也遇到了同样的问题。在我的应用程序中有三个片段A -> B -> C,我需要从C返回到A。在我的情况下,我使用popBackStack()关闭当前片段并返回到上一个片段,之后任何尝试从A导航的操作都会抛出Navigation xxx is unknown to this NavController异常。

最终我使用navigate()而不是从后退栈中弹出片段来返回到A。正确使用popUpTopopUpToInclusive设置解决了这个问题(请参见文档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>

0

我是用这种方式

@Override
public void onBackPressed() {

 if(myNavController.getCurrentDestination().getId()==R.id.startDestinationId)
 /** do something */
 else myNavController.popBackStack();

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接