guys.
This must be a silly question but i'm not managing to work this out. My scenario is: i have in my MainActivity a BottomNavigation which i navigate over three fragments. And my problem is that when the back button (from android bottom navigation toolbar) is pressed the previous fragment opens but i want the app to close. So my question is: how i manage to prevent the previous fragments to open?
PS: I know it has something to do with FragmentMananger back stack but i did not understand how to use it.
PS2: Sorry for bad english.
The fragments are on the backstack.
Edit:
Work with FragmentTransaction and use addToBackStack (null)
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
Override the onBackPressed() method in your activity.
#Override
public void onBackPressed() {
finish(); //This would close the app
}
Word of caution. This would close the activity in all the cases when the user presses back. To avoid this perhaps you would like to create something like this:
#Override
public void onBackPressed() {
if(someCondition) {
finish(); //This would close the activity
}
else {
super.onBackPressed(); //Fallbacks to default Android implementation
}
}
Related
I have 3 fragments A, B and C with A being the start destination of my nav graph. When the user starts the app, I check in fragment A if there are previously stored results. If there are, I want to navigate straight to fragment C. I have managed to get this to work. However, when the user presses back in fragment C in this case, I want them to be taken to fragment B instead of A, and that's what I need help figuring out.
Note: Fragment A is just a setup fragment which is only visited once when the app starts. Which means when the user presses back from fragment B, they are taken to OS home screen.
You can override onBackPress() and replace whatever fragment you are in with FragmentB like this
#Override
public void onBackPressed() {
int stackCount = getFragmentManager().getBackStackEntryCount();
if (stackCount == 1) {
super.onBackPressed(); // if you don't have any fragments in your backstack yet.
} else {
// just replace container with fragment as you normally do;
FragmentManager fm = getFragmentManager();
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);//clear backstackfirst and then you can exit the app onbackpressed from home fr
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.container, new FragmentB());
transaction.commit();
}
}
This is the original answer ,you can take a look answer by Rainmaker
You can override your onBackPressed on fragment C and call your navController to go back to fragment b creating a new action from C to B
navController.navigate(R.id.action_CFragment_to_BFragment)
I have 3 fragments Fragment1, Fragment2 and Fragment3 and navigation is like
Fragment1->Fragment2->Fragment3
But on back press From Fragment3 go back to Fragment2 after completing some task like from Fragment2. And from Fragment1 finish this activity.
what will be the best method to do this task.
As per your question just you have to add addToBackStack() method before commit() transaction.
for example:
FirstFragment firstFragment = new FirstFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.article_fragment, firstFragment)
.addToBackStack(null).commit();
Add second and third fragment same as above manner and just add code in onBackPressed() Override method.
for example:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
Please follow the process.
1. When you add fragment add below code to your code
fragmentTransaction.addToBackStack(null);
Then back button handle from the activity.
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount()>0){
getFragmentManager().popBackStack();
}else {
super.onBackPressed();
} }
It will be working perfectly. Happy coding.
There is no need to handle OnBackPress inside Fragment. When you performing Fragment transaction, you can put your fragment to BackStack:
When there are FragmentTransaction objects on the back stack and the user presses the Back button, the FragmentManager pops the most recent transaction off the back stack and performs the reverse action (such as removing a fragment if the transaction added it).
More details you can get from this article.
I’m developing an android application that makes heavy use of fragments, I’m running into an issue and I’ve been unable to find a solution so far.
The flow is this: the app is launched and MainActivity is the first responder, now, depending on user interaction several fragments gets loaded and pushed onto the stack.
Here is an example:
Main Activity -> fragment A -> fragment B -> fragment C -> etc..
Back history is enabled like so:
fragment C -> fragment B -> fragment A -> etc..
Everything works perfectly fine as long as my application is in foreground but everything breaks when the application goes in background.
If I’m on fragment B for example and I press the home button the application goes in background and when I restore it back it starts from MainActivity with fragment A.
Also, the toolbar shows the title of fragment B and, since fragment A contains a recyclerview I can see parts of fragment B between item rows, like a background image.
This is how I load fragments:
public void loadFragment(Fragment fragment, Boolean addToStack) {
// Load fragment
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_container, fragment);
fragmentTransaction.addToBackStack(null);
// show back button
if (addToStack) {
// Code to show the back button.
}
else if (fragmentManager.getBackStackEntryCount() > 0 && !addToStack) {
hideBackButton();
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
fragmentTransaction.commitAllowingStateLoss();
}
I call this function from MainActivity and from the fragments:
MyFragment theFragment = new MyFragment();
MainActivity.instance.loadFragment(theFragment, true);
What I want to achieve is that when the application is restored it gets straight to the previously loaded fragment, keeping the entire "back" history. How can I do this?
I'm not sure if other portions of code are needed, but if so I'll post them as required.
call the onResume() function:
public void onResume(){
Fragment frg = null;
frg = getSupportFragmentManager().findFragmentByTag("Your_Fragment_TAG");
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.detach(frg);
ft.attach(frg);
ft.commit();
}
Ok so, after a lot of research I found the issue… and the issue was a mistake of mine.
I’d like to report it here for everyone that might run into the same issue.
At first I tried to force fragment replacement on onResume() function like so:
Fragment f = getSupportFragmentManager().findFragmentById(R.id.container);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_container, f);
fragmentTransaction.addToBackStack(null);
However android should handle all of this automatically, at least in my knowledge, and so I tried to dig further and I finally narrowed it down to my onStart() method.
Basically I was registering the EventBus and making a function call
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
UserNetworkManager userNetworkManager = new UserNetworkManager(MainActivity.mainActivity);
userNetworkManager.fetchFeed();
}
This code was creating the issue and after all it was not necessary to put it there, so I moved it to the onCreate() method, cleaned up my code a little bit and everything works fine now.
I want to be able to reverse a replace FragmentTransaction by using addToBackStack():
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
Fragment scheduleFragment = new ScheduleFragment();
fragmentTransaction.replace(R.id.content_container, scheduleFragment, "scheduleFragment");
fragmentTransaction.addToBackStack("scheduleFragment");
fragmentTransaction.commit();
but after that, clicking the back button does nothing.
From the doc and it's supposed to reverse the transaction.
What am I missing?
The right way to do this is using onBackPressed() method to catch that back event in your app, and then "pop" the backStack with popBackStack(). For example:
public void onBackPressed()
{
// Catch back action and pops from backstack
// (if you called previously to addToBackStack() in your transaction)
if (getSupportFragmentManager().getBackStackEntryCount() > 0){
getSupportFragmentManager().popBackStack();
}
// Default action on back pressed
else super.onBackPressed();
}
PD: Sorry for the delay answering, but I just saw your question. Hope it helps!
Try fragmentTransaction.addToBackStack(null)
The parameter for addToBackStack() is an optional name for the back state, you do not use the tag in the replace() method which is just an optional tag for the fragment.
You can read more about this here.
I's been a while but I hope this will help someone.
fragmentTransaction.addToBackStack(null) won't work if you are extending AppCompatActivity. It works well in Activity. I couldn't find the reason.
I implemented my own Fragment stack:
public Fragment addFragmentToStack(Fragment fragment){
if(MyApplication.fragmentStack.size()>20){
MyApplication.fragmentStack.remove(0);
}
return MyApplication.fragmentStack.push(fragment);
}
public void onBackPressed() {
if (MyApplication.fragmentStack.size() > 0) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_container, MyApplication.fragmentStack.pop());
ft.commit();
}
else{
finish();
}
}
when fragment use addToBackStack(null) method and click a method many times in an activity, the fragment page will save to back stack everytime, when I press back key, it will restore the same page, how to add the same fragment to stack just one time?
mSettingBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
SettingFragment settingFragment = new SettingFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.replace(R.id.left_framelayout, settingFragment);
transaction.addToBackStack(null);
transaction.commit();
}
});
When adding your Fragment to the backstack you should also pass a TAG to be able to identify that Fragment:
.addToBackStack(SettingsFragment.TAG);
Prior to adding the Fragment you will be able to check if this Fragment is allready in the backstack using :
getFragmentMangager().findFragmentByTag(SettingsFragment.TAG);
This will return null if the Fragment is not allready added.