【问题标题】:Navigation DESTINATION_NAME is unknown to this NavController, ReOpening fragment previously closed using navController.popBackStack()?此 NavController 不知道导航 DESTINATION_NAME,重新打开之前使用 navController.popBackStack() 关闭的片段?
【发布时间】:2019-01-24 01:24:05
【问题描述】:

我在我的应用程序中使用导航组件,最近它工作正常,但在将项目更新到AndroidX 后,我收到错误navigation destination DESTINATION_NAME is unknown to this NavController 只有当那个目的地(我要打开的)是以前使用navController.popBackStack() 自行关闭。此外,如果我从MainActivity 关闭 DESTINATION 片段,则没有错误,但仅发生错误片段是使用popBackStack 从自身关闭的。如下所示

目标片段

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)

【问题讨论】:

    标签: android android-architecture-components android-jetpack android-architecture-navigation


    【解决方案1】:

    我就是这样用的

    @Override
    public void onBackPressed() {
    
     if(myNavController.getCurrentDestination().getId()==R.id.startDestinationId)
     /** do something */
     else myNavController.popBackStack();
    
    }
    

    【讨论】:

      【解决方案2】:

      我有同样的问题。在我的应用程序中有三个片段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>
      

      【讨论】:

        【解决方案3】:

        我在 DestinationFragment 中使用 SingleLiveEvent 来观察 MainActivity 的后压,因为我已经在我的问题中提到了这一点。所以问题出在SingleLiveEvent 我注意到我不小心将fun observe(owner: LifecycleOwner, observer: Observer&lt;in T&gt;) 的代码更改为

        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*//})
        }  
        

        现在我的代码可以正常工作了

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

          猜你喜欢
          • 2020-03-01
          • 1970-01-01
          • 2020-08-24
          • 2020-08-08
          • 1970-01-01
          • 2021-05-02
          • 1970-01-01
          • 2021-05-02
          • 2013-08-31
          相关资源
          最近更新 更多