I'm calling NavController.popBackStack() to go back to a previous fragment in an app. It actually navigates back, but it seems a new instance of the previous fragment is created instead of reusing the previous one. Let me explain what's happening with more detail:
From FragmentA I open FragmentB by calling this in the onClick method of a button:
findNavController(FragmentA.this).navigate(R.id.fragment_b);
Also I disable that button by calling button.setEnabled(false) before doing that.
Now, the FragmentB is created and everything works as expected.
Then I want to go back to the previous instance of FragmentA as it was, but when I call
findNavController(FragmentB.this).popBackStack();
it goes back to FragmentA, but there it calls onCreateView and hence the button that I had previously disabled appears enabled again, which is not the expected behaviour.
I tried with navigateUp() instead, but the result is the same.
Any ideas?
Thanks a lot in advance!
When you are navigating to the other fragment via findNavController().navigate()
, fragment transaction manager remains the node of the fragment in the chain of fragments(or stack of fragments), but it also removes View Hierarchy of previous fragment. So when you've navigated back to previous screen, there is no Views of previous fragment in the memory, that's why it recreates views(View Hierarchy) again.
If you are navigating between fragments, you usually call findNavController().navigate()
.
findNavController().navigate()
calls the FragmentNavigator.navigate()
.
FragmentNavigator.navigate() calls the ft.replace(mContainerId, frag)
.
Here is documentation for FragmentTransaction.replace():
Replace an existing fragment that was added to a container. This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.
Solution: You can save the disable state in the somewhere that remains during navigation, like: ViewModel, Singleton class. But I strongly recommend the ViewModel. And when you've navigated back the fragment and after recreating the View Hierarchy, you can restore the button state.
Fragment:onViewCreated() {
viewModel.buttonState.observe(viewLifecycleOwner) { state->
myButton.isEnabled = state.isEnabled
}
}
ViewModel {
val buttonState = MutableLiveData<ButtonState>()
fun onSomeButtonClicked() {
buttonState.value = ButtonState(false)
}
class ButtonState(
val isEnabled: Boolean
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With