This case might be a unique one because I do have some complicated navigation logic and I'm using extension functions(which I will share below shortly).
- Imagine having a Fragment(A) opening a BottomSheetFragment(B)
- And the BottomSheetFragment(B) has a button inside.
- Tapping on the button dismisses the BottomSheetFragment(B) and navigates to a new Fragment(C).
To handle this case, I'm using 2 extension functions:
fun <T> Fragment.setNavigationResult(key: String, result: T) {
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, result)
}
fun <T> Fragment.getNavigationResult(key: String) = findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<T>(key)
Implementation of setNavigationResult
in BottomSheetFragment(B)
loginButton.setOnClickListener {
dismiss()
setNavigationResult(EVENT_CUSTOMER_SIGNUP_LOGIN, Event(true))
}
Implementation of getNavigationResult
in Fragment(A)
getNavigationResult<Event<Boolean>>(EVENT_CUSTOMER_SIGNUP_LOGIN)?.observe(viewLifecycleOwner) { event ->
event.value?.let {
findNavController().navigate(R.id.openCustomerLogin)
}
}
The application crashes with the below error:
java.lang.IllegalArgumentException: Navigation action/destination openFragmentC cannot be found from the current destination Destination(FragmentB)
What I don't understand here is, the current destination is still BottomSheetFragment(B)
even I called dismiss
before.
When I add a delay before navigating to FragmentC, then the application does not crash.
lifecycleScope.launch {
delay(250)
findNavController().navigate(R.id.openCustomerLogin)
}
I don't like the solution with delay
, because it's not practical and can easily be forgotten in new implementations.
Sorry for the long post, I will appreciate it if you share your thoughts on this and assist me.