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've created a fragment that shows gridview and when any griditem is clicked it leds to another fragment. But when I press the physical backbutton the app closes instead of going back to previous fragment (i.e. fragment containing gridview). How can I solve this?
try this one
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
'addToBackStack' is used for moving back to previous fragment, you can use a common Function
in your Main activity for changing fragment.
public void change_fragment(Fragment fragment, int frame) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
//trans.setCustomAnimations(R.anim.enterfrom_left, R.anim.exit_to_right,R.anim.enterfrom_left, R.anim.exit_to_right);
trans.replace(frame, fragment);
trans.addToBackStack("hai" + frame);
trans.commit();
}
you can call it from Main activity like this
change_fragment(new Frag(),R.id.fl_main_frag_container);
you can call it from another fragment like this
((MainActivity)getContext()).change_fragment(new Frag(), R.id.fl_main_frag_container);
I have an activity which uses fragments, when the activity is first created, it displays a first fragment which is not added to back stack cause I don't want to have an empty activity when user presses back.
The fragments loaded after that are added to back stack.
So I have the behavior I want, except: user can open fragments and press back to go back to the previous fragment, up until they reach the first fragment because if they press back at this time, the activity is closed, which I don't want.
So I'd like to know a good solution to prevent back button pressed but only when the first fragment is displayed.
Add .addToBackStack(null) when you call the new fragment from activity.
FragmentTransaction mFragmentTransaction = getFragmentManager()
.beginTransaction();
....
mFragmentTransaction.addToBackStack(null);
-Add onBackPressed() to your activity
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
}
else {
getFragmentManager().popBackStack();
}
}
Solved like this:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount()> 0) {
super.onBackPressed();
}
}
in your activity class add below code in onBackPressed method;
#Override
public void onBackPressed() {
int backstack = getSupportFragmentManager().getBackStackEntryCount();
if (backstack > 0) {
getSupportFragmentManager().popBackStack();
}
else{
super.onBackPressed();
//System.exit(0);
}
}
hope this help.
I want to have a Fragment which provides the ability to create someting.
After that i want to show the new "someting" in another fragment. After pressing the back button on the device i want to go back to the MainFragment and not to the CreateFragment (this works well). But after that the ShowFragment is still visible.
Here is my code:
In my MainActivity i got a MainFragment which has a button "Create".
After tap the button i load a "Create" Fragment.
fragmentManager.beginTransaction()
.replace(R.id.container, CreateFragment.newInstance())
.addToBackStack("Create")
.commit();
If the user has entered some details he taps the "Ok" Button. This fires the following on the MainActivity.
fragmentManager.beginTransaction()
.replace(R.id.container, ShowFragment.newInstance(id))
.commit();
So far so good, but here comes the problem.
If the user taps the back button on the device he gets back to the MainFragment BUT the ShowFragment is still visible (under the MainFragment).
Update
This is what happens:
MainFragment > CreateFragment > ShowFragment > (BACK Button) > MainFragment (ShowFragment in the back)
Just pop the ShowFragment from the stack on the onBackPress Event as below:
#Override
public void onBackPressed() {
final Fragment fragment = fragmentManager.findFragmentById(R.id.container);
if (fragment != null) {
fragmentManager.popBackStack();
} else {
super.onBackPressed();
}
}
Press the back button of fragment ShowFragment within your ShowFragment fragment will call the onBackPressed() method. Then when you call method popBackStack(), it will return you back to the CreateFragment.
Sample code -
public void onBackPressed()
{
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.popBackStack();
}
See the post how-to-back-to-previous-fragment-on-pressing-manually-back-button-of-indivisual-fragment for more info with similar situation.
Say I have an activity that has fragments added programmatically:
private void animateToFragment(Fragment newFragment, String tag) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, newFragment, tag);
ft.addToBackStack(null);
ft.commit();
}
What is the best way to return to the previous fragment that was visible?
I found Trigger back-button functionality on button click in Android but I'm thinking simulating a back key event isn't the right way to go about it (and I can't get it to work either):
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
Calling finish() just closes the activity which I'm not interested in.
Is there a better way to go about this?
Look at the getFragmentManager().popBackStack() methods (there are several to choose from)
http://developer.android.com/reference/android/app/FragmentManager.html#popBackStack()
To elaborate on the other answers provided, this is my solution (placed in an Activity):
#Override
public void onBackPressed(){
FragmentManager fm = getFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
Log.i("MainActivity", "popping backstack");
fm.popBackStack();
} else {
Log.i("MainActivity", "nothing on backstack, calling super");
super.onBackPressed();
}
}
When we are updating/add the fragments,
Should Include the .addToBackStack().
getSupportFragmentManager().beginTransaction()
.add(detailFragment, "detail") // Add this transaction to the back stack (name is an optional name for this back stack state, or null).
.addToBackStack(null)
.commit();
After that if we give the getFragments.popBackStackImmediate() will return true if we add/update the fragments, and move back to the current screen.
Android Navigation architecture component.
The following code works for me:
findNavController().popBackStack()
These answers does not work if i don't have addToBackStack() added to my fragment transaction but, you can use:
getActivity().onBackPressed();
from your any fragment to go back one step;
Add those line to your onBackPressed() Method. popBackStackImmediate() method will get you back to the previous fragment if you have any fragment on back stack
`
if(getFragmentManager().getBackStackEntryCount() > 0){
getFragmentManager().popBackStackImmediate();
}
else{
super.onBackPressed();
}
`
This solution works perfectly for bottom bar based fragment navigation when you want to close the app when back pressed in primary fragment.
On the other hand when you are opening the secondary fragment (fragment in fragment) which is defined as "DetailedPizza" in my code it will return the previous state of primary fragment. Cheers !
Inside activities on back pressed put this:
Fragment home = getSupportFragmentManager().findFragmentByTag("DetailedPizza");
if (home instanceof FragmentDetailedPizza && home.isVisible()) {
if (getFragmentManager().getBackStackEntryCount() != 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
} else {
//Primary fragment
moveTaskToBack(true);
}
And launch the other fragment like this:
Fragment someFragment = new FragmentDetailedPizza();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container_body, someFragment, "DetailedPizza");
transaction.addToBackStack("DetailedPizza");
transaction.commit();
Kotlin Answer
First, call Fragment Manager.
After, to use onBackPressed()
method.
Coding in Android Studio 4.0 with Kotlin:
fragmentManager?.popBackStack()
Programmatically go back to the previous fragment using following code.
if ( getFragmentManager().getBackStackEntryCount() > 0)
{
getFragmentManager().popBackStack();
return;
}
super.onBackPressed();
To make that fragment come again, just add that fragment to backstack which you want to come on back pressed, Eg:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragment = new LoginFragment();
//replacing the fragment
if (fragment != null) {
FragmentTransaction ft = ((FragmentActivity)getContext()).getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackStack("SignupFragment");
ft.commit();
}
}
});
In the above case, I am opening LoginFragment when Button button is pressed, right now the user is in SignupFragment. So if addToBackStack(TAG) is called, where TAG = "SignupFragment", then when back button is pressed in LoginFragment, we come back to SignUpFragment.
Happy Coding!
By adding fragment_tran.addToBackStack(null) on last fragment, I am able to do come back on last fragment.
adding new fragment:
view.findViewById(R.id.changepass).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, new ChangePassword());
transaction.addToBackStack(null);
transaction.commit();
}
});
Following Kotlin code useful to me
1. Added in Simple Activity class with multiple fragments used
override fun onBackPressed() {
if (supportFragmentManager.backStackEntryCount > 0) {
Log.i(TAG, "=============onBackPressed - Popping backstack====")
supportFragmentManager.popBackStack()
} else {
Log.i(TAG, "=============onBackPressed called because nothing on backstack====")
super.onBackPressed()
}
}
2. Added in BottomNavigationView Activity class with multiple fragments used
override fun onBackPressed() {
Log.e(TAG, "=============onBackPressed")
val navController = findNavController(R.id.nav_host_fragment)
when (navController.currentDestination!!.id) {
R.id.navigation_comments, R.id.navigation_my_posts -> {
menuItemPosition = 0
navController.navigate(R.id.navigation_home)
Log.i(TAG, "=============onBackPressed - Popping backstack with First fragment ====")
}
else -> {
Log.i(TAG, "=============onBackPressed called because nothing on backstack====")
super.onBackPressed()
}
}
}
I came here looking or the same idea, and in the meantime i came up with own, which I believe is not that bad and works if with ViewPager.
So what I did, is to override the onBackPressed method in the parent activity that holds the viewPager, and set it to always go back minus 1 position until it reaches the first fragment, then closes the activity.
#Override
public void onBackPressed() {
if(viewPager.getCurrentItem()>0){
viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
} else {
super.onBackPressed();
this.close();
}
}
private void close(){
this.finish();
}
This might have a downfalls, like it only goes back one way left each time, so it might not work great if there are tabs and you switch positions with fragments skipped, ( going from 0 to 2, and then pressing back would put you on 1, instead of 0)
For my case tho, with 2 fragments in viewPager without tabs, it does the job nicely.
getActivity().getSupportFragmentManager().popBackStackImmediate();
OR
getActivity().onBackPressed();
Try below code:
#Override
public void onBackPressed() {
Fragment myFragment = getSupportFragmentManager().findFragmentById(R.id.container);
if (myFragment != null && myFragment instanceof StepOneFragment) {
finish();
} else {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
}