I've got a navigation drawer. In that navigation drawer I've got five fragments. When I select a fragment, it shows up. When I press the back button, it goes to the previous fragment. However, I need the back button to send you back to the first fragment. How do I do this?
Overwrite the onBackPressed() method in your Activity:
#Override
public void onBackPressed(){
FragmentTransactionn ft = getFragmentManager().beginTransaction();
ft.replace([your fragment container], yourfirstFragment, TAG_FRAGMENTFIRST);
ft.commit();
}
Apparently you already figured out how to show fragments. I'd suggest using the same code you use in your navigation drawer in the public void onBackPressed() to draw up the first fragment again. To make users able to exit the app, check if the first fragment is already visible. If so, call super.onBackPressed() or finish().
Related
I have only one activity in my application with multiple fragments. Whenever a user opens the app, it starts with startupFragment. Whenever user navigate through the fragments and presses back, it takes him back to startupFragment. But when in the startupFragment, I want user, when clicked back, to be able to close the application. Now, here is the code, when the application is started for creating the fragment.:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Set starting fragment
StartupFragment startupFragment = new StartupFragment();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().add(R.id.content_main, startupFragment, "startupFragmentTag").commit();
}
As you can see, I have added the tag "startupFragmentTag" to be able to identify it. This is my code onBackPressed:
#Override
public void onBackPressed()
{
Fragment startup = getFragmentManager().findFragmentByTag("startupFragmentTag");
if(startup == null) {
android.support.v4.app.FragmentManager manager = getSupportFragmentManager();
StartupFragment startupFragment = new StartupFragment();
manager.beginTransaction().replace(R.id.content_main, startupFragment, "startupFragmentTag").commit();
} else {
finish();
}
}
So basically what I tried here, is when user is in another fragment, when the user presses back, it will take him/her back to startupFragment. But when in that fragment, when pressing back again, I want the user to be able to exit the application, which won't happen given the code now.
I find the startupFragment by its tag and check if it exists. If not, it will take back the user to it. But if it exists, user should be able to quit, that why finish() is called.
Does the previous fragments not get destroyed? But that shouldn't be the case, because even if I open the app and instantly press back, it won't exit the app.
What am I doing here wrong?
It looks like all you need to do is add each Fragment to the back stack on each FragmentTransaction, and then pop each Fragment from the back stack in onBackPressed().
First, modify onCreate() so that on each transaction, it calls addToBackStack():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Set starting fragment
StartupFragment startupFragment = new StartupFragment();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.content_main, startupFragment, "startupFragmentTag")
.addToBackStack(null)
.commit();
}
Then, in onBackPressed(), just pop from the back stack if you're not on the starting Fragment. If you're on the starting Fragment, and back is pressed, just call super.onBackPressed(), which will exit the app:
#Override
public void onBackPressed() {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 1) {
//Go back to previous Fragment
fragmentManager.popBackStackImmediate();
} else {
//Nothing in the back stack, so exit
super.onBackPressed();
}
}
You're working with fragments, so to finish your app you need to finish the parent activity.
Try this to finish the activity from startupfragment:
getActivity().finish();
Probably because you've used beginTransaction().add() to add the Fragments including startupFragment and other Fragments on top of it. Then you will always be able to find it using getFragmentManager().findFragmentByTag(), because all Fragments added will be in the Fragment stack (while the find method is actually to find the Fragment with the tag in the stack).
Tips based on what you want to impl:
beginTransaction().replace() will replace instead of adding a Fragment, this way you will only be able to "find" one existing Fragment if you always replace it. i.e. always one Fragment in the stack.
You may want to use getFragmentManager().findFragmentById() to get current showing Fragment (on top of the Fragment stack), instead of findFragmentByTag, if there're several Fragments in the stack which are added not replaced as mentioned above.
When using beginTransaction().add(), you may want to use fragmentManager.addOnBackStackChangedListener() to monitor the Fragment stack changes. Then you probably don't have to handle onBackPressed(). Then in the in the listener you only need to retrieve current Fragment on top stack and see what it is and add your logic there.
I have fragment A and adding fragment B in same container (not replacing). I am adding this transaction on backstack also. Now, when device back is pressed, fragment B will be removed and fragment A will become visible. I want to do something when fragment A becomes visible. I searched lot but could not find anything helpful.
Note - I don't want to add backstackchangelistner and call onResume on that fragment.
You can override onHiddenChanged(boolean hidden) in a Fragment.
This will be called when its shown/hidden.
I use the same approach in my app, where i add a fragment and hide the old one, and then use the onHiddenChanged callback when the user presses Back, and the old fragment is shown again.
As you have 2 entries in Back stack, you can check back stack count on
Back Pressed method.
FragmentManager mFragmentManager = getSupportFragmentManager();
int count= mFragmentManager.getBackStackEntryCount();
if(count==1){
// do your work
}
you can try
#Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
}
or
`fragment.isVisible();`
I'm so very confused and have been reading on this topic for a while.
I have a MainActivity that has multiple possible contents (switched between via navigation drawer), which I've set via multiple fragments (lets call them Fragment1, Fragment2 and Fragment3).
That works fine.
One of my fragments, Fragment3, is a View that can segue to a new activity, View2.
View2 has a back button. When I press on the View2 back button I want to see Fragment3 on my MainActivity, not Fragment1, which is what I currently get. This is because OnCreate, by default, loads Fragment1.
What is the best way to do this?
Thanks so much in advance! (vent: iOS makes this so much easier).
The official documentation for Fragments states that you should make sure to call addToBackStack() before commiting your fragment transaction on your first activity holding the 3 fragments.
In order to go back to the last used fragment from the second activity , you should override the onBackPressed() method in this activity :
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
The documentation is very complete on the subject : Read it here
Update:
I just added this to the back button code:
finish();
return true;
I had to do it within onOptionsItemSelected(MenuItem item)... for some reason onBackPressed is not fired.
I have two questions:
I want to remove all fragments in back-stack when user come back to main page.
However when I call following statement there is a flickering on the main page.
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
how to remove this flickering? I tried the method here no luck.
Pop the fragment backstack without playing the Pop-Animation*
In fragment transition i use replace method. But in some
transitions I dont want to reload the entire data when user presses
the back button. To implement this I used hide() and add() methods.
When this is done above back-stack remove process becomes really bad
with so many animations.
Is there a best practice to implement this?
I had exactly the same issue as (1). Here is what worked for me:
the transaction that shows the first fragment is added to the backstack using a named backstate, eg: "bottom".
the backstack is cleared with popBackStackImmediate("bottom", ...INCLUSIVE).
So, whenever I want to replace whatever is in the backstack with a new fragment I use the following function:
protected void showInitialFragment(Fragment fragment) {
getSupportFragmentManager()
.popBackStackImmediate(BOTTOM_BACK_STATE, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_content, fragment)
.addToBackStack(BOTTOM_BACK_STATE)
.commit();
}
I also had to override onBackPressed() like this:
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
finish();
} else {
super.onBackPressed();
}
}
Hope this helps!
Found an easy method https://stackoverflow.com/a/67005552/7418129. Sorry if I'm late. But it will definitely help someone.
The best solution for me was to add setReorderingAllowed(true).
Example:
parentFragmentManager.commit {
setReorderingAllowed(true)
addToBackStack(null)
setCustomAnimations(R.anim.enter_right, R.anim.exit_left, R.anim.enter_left, R.anim.exit_right)
replace<AnotherFragment>(R.id.fragment_container)
}
I am using a navigation drawer and fragments to inflate the main activity.
However when I press the back button it closes the application which is obvious with fragment setup.
What I want is that when the user clicks the back button they go to the home page fragment if its not currently the view, but if they are on the home page I want the app to close.
How to go around this problem?
Overriding the back button would be a REALLY BAD idea, as it will hurt more than help.
If you want to add a Fragment that will not be replaced (Your initial "HomePageFragment"), just add this line:
transaction.addToBackStack(null);
Which will give you something like:
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, fragment, TAG_FRAGMENT);
transaction.addToBackStack(null);
transaction.commit();
If you add some other Fragments, don't add them to the back stack.
You should override the onBackPressed method in the activity class and using that you can determine whether you need to switch back to your home fragment or call super.onBackPressed().