I am trying to figure out an easy solution without overcomplicating things on preventing certain screens in the app from going back when they use the back button of the android device however, I am not sure which approach is best in my situtation.
The application is not using navigation component and its quite a large project already to implement that, there are screens such as the login which if you press the back button after login in, it will take you back to the login. Fortunatly the login screen is an activity so I can just do finish();
after startActivity(i);
and that sorts it out however, there are multiple fragments after login in which causes issues such as duplications and re-entering values that you did not mean to by simply pressing the back button.
What I am currently doing is fragmentTransaction.addToBackStack(null);
before I do commit();
I tried removing the fragmentTransaction.addToBackStack(null);
where I did not wanted it and it kind of worked but it would not take you back to a specific screen when you would use the back button, it will take you to the last fragmentTransaction.addToBackStack(null);
used and that is causing confusion in some cases.
Example of what I am usually doing:
Fragment enqFragment = new EnqFragment();
//Fragment findCustomerFragment = new AppInformationFragment();
FragmentTransaction transaction = requireActivity().getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, enquiryFragment);
transaction.addToBackStack(null); // I would comment this out if I did not want to go back here
transaction.commit();
What I want to do is go from A to B to C but when I press back I want to go back to A and in some cases when C goes to D and back is pressed I want to again go to A or B depends on the occasion. Is Navigation components the most ideal way to go with this or is there an easier solution to achieve this and what are the pros and cons?
Well first you need to keep in mind that when the user pressed the back button or when onBackPressed
is called, the default behaviour is popping off the latest fragment from the stack. You can customise this behaviour as follows as it is easier than going and overriding onBackPressed
in each case
Using the navigation component which was introduced in Jetpack
SOLUTION 1:
The app:popUpTo
and app:popUpToInclusive
are exactly what you may be looking for
Via the documentation,the xml attributes will
Pop up to a given destination before navigating. This pops all non-matching destinations from the back stack until this destination is found
Let me explain this to you with three fragments A
, B
, C
A (start) -> B -> C
if I want to navigate to C
and pop all including A
(startscreen) then the code will be:
<action
android:id="@+id/B_to_C"
app:destination="@id/C"
app:popUpTo="@+id/A"
app:popUpToInclusive="true" />
if I want to navigate to C
and pop all excluding A
then the code will be:
<action
android:id="@+id/action_B_to_C"
app:destination="@id/C"
app:popUpTo="@+id/A"/>
SOLUTION 2:
Using the popBackStack
method of the NavController
class which does the same job as the onBackPressed
but in an elegant way
If you have three fragments : A
, B
, C
And you are currently in fragment C
and would like to go back to A
before navigating anywhere(or not navigating anywhere if you please)
NavController controller = Navigation.findNavController(view);
controller.popBackStack(R.id.fragmentB, true);
OR
NavController controller = Navigation.findNavController(view);
controller.popBackStack(R.id.fragmentA, false);
where true
or false
will indicate if you actually want the destination to stay(false
) or be popped off the stack too (true
)
Using the same without navigation component i.e. older FragmentManager
class
The example above nicely explains the behaviour, however you can use methods like popBackStack
, and its variations