Navigation DESTINATION_NAME is unknown to this NavController, ReOpening fragment previously closed using navController.popBackStack()?

允我心安 提交于 2020-07-18 10:19:12

问题


I am using Navigation Component in my app , recently it was working correctly but after updating project to AndroidX I am getting error navigation destination DESTINATION_NAME is unknown to this NavController only if that destination(Which I'm going to open) is previously closed from itself using navController.popBackStack(). Also, There is no error if I close DESTINATION fragment from MainActivity, But Error only Occurs fragment is closed from itself using popBackStack. like below

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

I Have also checked related Question but no help Similar Question.

NOTE: I am using the latest version of the navigation library (alpha05)


回答1:


The previous value likely still exists in the view model and is triggering right away. I'd recommend using an interface to handle your back button delegation instead of an observer. That should fix the usage.

What's happening is you're popping too far up your back stack to the point where you don't have an active graph anymore. This is happening because your observer is getting triggered more often than it should. To see this, I'd recommend debugging that line and inspecting the graph right before a crash. It's likely to be null.




回答2:


I was using SingleLiveEvent in DestinationFragment to observe back press from MainActivity as I have already mentioned this in my question. So the problem was in SingleLiveEvent I noticed that I have accidently changed code of fun observe(owner: LifecycleOwner, observer: Observer<in T>) to

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

Here you can see I was calling super function twice which calls onChanged of observer twice in Fragment , below code is called twice
Navigation.findNavController(requireActivity(), R.id.main_nav_host).popBackStack() which popBackStack() twice.
Then I have changed observe function like below

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

Now my code works fine




回答3:


I had the same issue. In my app there were three fragments A -> B -> C and I had to return to A from C. In my case I used popBackStack() to close the current fragment and return to the previous one, after that any attempt to navigate from A threw Navigation xxx is unknown to this NavController exception.

I ended up using navigate() to A instead of pop fragments from back stack. Using popUpTo and popUpToInclusive settings properly fixed the issue (see docs 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>



回答4:


i am use this way

@Override
public void onBackPressed() {

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

}


来源:https://stackoverflow.com/questions/51887968/navigation-destination-name-is-unknown-to-this-navcontroller-reopening-fragment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!