In my app have a navigation flow like this
AuthFragment --> SellerMainScreenFragment -----> pay_nav_graph (Nested Graph)
|
|----> CreditFragment---------
| |
|----> CreditAddFragment <---|
|
|-------> TransactionResultFragment
Now when the app try to navigate from SellerMainScreenFragment
to CreditAddFragment
, everything works fine and upon pressing the back button in the latter fragment, the app returns to the former. The navigation code is
adapter.wasAddBalPressed.observe(viewLifecycleOwner, Observer {
if (it != NO_VAL)
findNavController().navigate(SellerMainScreenFragmentDirections.actionSellerListScreenFragmentToCreditAddFragment(it))
})
But when the app navigates from CreditFragment
to CreditAddFragment
, upon pressing the back button in the CreditAddFragment
, the app doesn't return to the previous fragment. The code goes :
val action = CreditFragmentDirections.actionCreditFragmentToCreditAddFragment(viewModel.userSellerPhoneNo)
findNavController().navigate(action)
I have tried setting a custom onBackPressedCallback
on the OnBackPressedDispatcher
like so
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
findNavController().popBackStack()
remove()
}
But even then it doesn't return to the previous fragment if it is the CreditFragment
but in the case of the SellerMainScreenFragment
, it works as intended.
I have also correctly set the app:defaultNavHost = true
in the NavHostFragment
.
At this point I have tried cleaning the project, invalidating the caches, cold booting the emulator and I tried to debug, but even then I can't find anything suspicious.
So if anyone can help out, please try to do so.Thanks.
Edit-1 :-
This is the navigation xml file that I am currently using in the app
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_nav_host_fragment"
app:startDestination="@id/authFragment">
<fragment
android:id="@+id/authFragment"
android:name="com.example.paylater.ui.AuthFragment"
android:label="AuthFragment"
tools:layout="@layout/fragment_auth">
<action
android:id="@+id/action_authFragment_to_sellerListScreenFragment"
app:destination="@id/sellerListScreenFragment"
app:popUpTo="@id/authFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/sellerListScreenFragment"
android:name="com.example.paylater.ui.SellerMainScreenFragment"
android:label="SellerListScreenFragment"
tools:layout="@layout/fragment_main_screen">
<action
android:id="@+id/listFragment_to_creditFragment"
app:destination="@id/creditFragment" />
<action
android:id="@+id/action_sellerListScreenFragment_to_pay_nav_graph"
app:destination="@id/pay_nav_graph" />
<action
android:id="@+id/action_sellerListScreenFragment_to_creditAddFragment"
app:destination="@id/creditAddFragment" />
</fragment>
<fragment
android:id="@+id/creditFragment"
android:name="com.example.paylater.ui.CreditFragment"
android:label="CreditFragment"
tools:layout="@layout/fragment_credit_enter_no">
<!--<action
android:id="@+id/action_creditFragment_self"
app:destination="@id/creditFragment" />-->
<action
android:id="@+id/action_creditFragment_to_creditAddFragment"
app:destination="@id/creditAddFragment" />
</fragment>
<fragment
android:id="@+id/creditAddFragment"
android:name="com.example.paylater.ui.CreditAddFragment"
android:label="CreditAddFragment"
tools:layout="@layout/fragment_credit_add">
<action
android:id="@+id/action_creditAddFragment_self"
app:destination="@id/creditAddFragment" />
<action
android:id="@+id/action_creditAddFragment_to_transactionResultFragment"
app:destination="@id/transactionResultFragment" />
<argument
android:name="sellerPhoneNo"
app:argType="string" />
</fragment>
<fragment
android:id="@+id/transactionResultFragment"
android:name="com.example.paylater.ui.TransactionResultFragment"
android:label="TransactionResultFragment"
tools:layout="@layout/fragment_transaction_result">
<action
android:id="@+id/action_transactionResultFragment_self"
app:destination="@id/transactionResultFragment" />
<argument
android:name="sellerPhoneNo"
app:argType="string" />
</fragment>
<action
android:id="@+id/action_global_sellerListScreenFragment"
app:destination="@id/sellerListScreenFragment" />
<navigation
android:id="@+id/pay_nav_graph"
app:startDestination="@id/payFragment">
<argument
android:name="sellerPhoneNo"
app:argType="string" />
<fragment
android:id="@+id/payFragment"
android:name="com.example.paylater.ui.PayFragment"
android:label="PayFragment">
<argument
android:name="sellerPhoneNo"
app:argType="string" />
<action
android:id="@+id/action_payFragment_to_processPaymentFragment"
app:destination="@id/processPaymentFragment" />
<action
android:id="@+id/action_payFragment_self"
app:destination="@id/payFragment" />
</fragment>
<fragment
android:id="@+id/processPaymentFragment"
android:name="com.example.paylater.ui.ProcessPaymentFragment"
android:label="ProcessPaymentFragment" />
</navigation>
</navigation>
Edit-2: Even after explicitly calling
findNavController().popBackStack(R.id.creditFragment, false)
in the onBackPressedCallback
, it still doesn't return to the previous fragment (CreditFragment
)
So basically the app was observing a MediatorLiveData
in the CreditFragment
and when it's value changed the navigation to the CreditAddFragment
happened.
But for some reason the MediatorLiveData
's value was maintained as it navigated to the next fragment, and upon pressing the back button, the app navigated to the previous fragment, but then navigated again to the CreditAddFragment
instantly, leading to it seeming as if the back navigation didm't happen.
I found this when I put Log
statements in both fragments' onViewCreated()
, after @MaryJane had suggested looking at the backstack behaviour.
Then only did I see this strange behaviour. So a big thanks to @MaryJane and for helping me solve this, and sorry to everyone for asking such a question.