Suppose we have activity with dynamic fragments. There is some "root" fragment, and it is added like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.replace(R.id.container, new RootFragment())
.addToBackStack("root")
.commit();
}
}
There are also some other fragments, which replaces this root fragment according to some logic. And we want to implement home button on ActionBar, which allows us to go from any fragment to the root. So, we call anywhere getActionBar().setDisplayHomeAsUpEnabled(true); and override onOptionsItemSelected in our activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
FragmentManager fm = getFragmentManager();
switch (id) {
case android.R.id.home:
fm.popBackStack("root", 0);
return true;
…
}
return super.onOptionsItemSelected(item);
}
This code works. But an issue appeared. When we press Back on root fragment, it just disappears from activity, we see empty screen and need to press Back once again to close application. I understand that it is correct behaviour according to the code I wrote and I need to remove addToBackStack to fix it. But in that case the home button implementation will not work.
The fix I see is overriding onBackPressed as following:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 1) {
super.onBackPressed();
} else {
finish();
}
}
But it seems unnaturally. Fragments should make code cleaner, not like this.
So, how to do it correct? I think that it is typical task and probably it is a silly question. But in official documentation I've found only one solution, and it is about Support library, which I don't want to use.
Or my dirty hack is OK?
I was working on the similar task in my project and in my opinion your "hack" is ok: since root Activity may itself have a layout, popping last fragment backstack state will lead to showing Activity in its initial state. I think this scenario is common and the fact that your root Activity has no layout is just a special case. My case, if you interested:
#Override
public void onBackPressed() {
if (fragmentManager.getBackStackEntryCount() <= (Const.isTablet ? 3 : 2)) {
Utils.getStyledAlertDialogBuilder(this, R.string.confirm_finish)
.setIcon(R.drawable.ic_app)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.finish, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.show();
return;
}
super.onBackPressed();
}
Related
I've got an Android application which is working fine, but I've found an annoying bug which I don't know what else do to solve it.
My application has a single Activity (call it HomeActivity; well, plus the Preferences Activity) and lots of Fragments. HomeActivity manages the replacement of every Fragment using this method (found in this thread and especially looking into the following comment):
public void switchFragment(Fragment pFragment, String pTagFragment){
String backStateName = pTagFragment;
boolean fragmentPopped = mFragmentManager.popBackStackImmediate (backStateName, 0);
if (!fragmentPopped){ //fragment not in back stack, create it.
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.replace(R.id.content_frame, pFragment);
ft.addToBackStack(backStateName);
ft.commit();
}
}
To replace a Fragment, what I do is the following:
switchFragment(new FragmentEuskalmet(), FragmentEuskalmet.FRAGMENT_NAME);
Here it's the problem: I navigate through several Fragments (say, 3 of them). Then, I wanna go back, so I press back 2 times. When I arrive to the last within the stack, a white screen is shown (i.e. white is shown in the place where the Fragment should be). The odd thing is that if I do a long press to my home button to show the recent apps and I choose again my application, the fragment gets loaded correctly.
I assume there might be something within my switchFragment method, e.g. it may be any issue related to the backStack. One important detail is that I've got written the so called empty constructor in every Fragment.
Can anybody lend me a hand? I can provide further code pieces if anybody request them.
Edit:
I've considered compulsory to type my sss method:
#Override
public void onBackPressed(){
invalidateOptionsMenu();
if(CURRENT_FRAGMENT != FragmentMapa.FRAGMENT_NAME){//"com.ingartek.bizkaimove.ui.FragmentMapa"){
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawerRightRelativeLayout);
}
if(mDrawer.isDrawerOpen(GravityCompat.START)){
mDrawer.closeDrawer(GravityCompat.START);
setToolbarSubtitle(mSubtitleAux);
}else{
setToolbarSubtitle(getString(R.string.app_name_subtitle));
if (getSupportFragmentManager().getBackStackEntryCount() == 1){
//finish();
showExitDialog();
}else {
super.onBackPressed();
popFragment();
}
}
}
I think I should rewrite this part:
}else {
super.onBackPressed();
popFragment();
}
Solution:
As #Ajay Pandya suggested, I leave the onBackPressed() that way:
#Override
public void onBackPressed(){
invalidateOptionsMenu();
if(CURRENT_FRAGMENT != FragmentMapa.FRAGMENT_NAME){//"com.ingartek.bizkaimove.ui.FragmentMapa"){
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawerRightRelativeLayout);
}
if(mDrawer.isDrawerOpen(GravityCompat.START)){
mDrawer.closeDrawer(GravityCompat.START);
setToolbarSubtitle(mSubtitleAux);
}else{
setToolbarSubtitle(getString(R.string.app_name_subtitle));
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
if (getSupportFragmentManager().getBackStackEntryCount() == 1){
//finish();
showExitDialog();
}else{
mFragmentManager.popBackStackImmediate();
}
} else {
super.onBackPressed();
}
}
}
You can manage back stack and screen for exit like
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
This is because you are adding all your fragments programmatically. On pressing back buttons, you eventually remove the first fragment that you added as well.
The reason you get it back on launching the application is because you add the fragment again.
I would suggest overwrite your back button. Whenever you pop fragment, check to see that it's not your first fragment and then pop it.
I'm building a pretty simple app. At it's core are 2 screens:
1) list-screen: a list of items
2) detail-screen: a detailed view of an item
I used one Activity (which extends AppCompatActivity) with an Action-Bar, a Navigation-Drawer and a main-content part (a FrameLayout).
I used 2 different fragments for the 2 screens:
When opening the app I inflate the list-fragment into the main-content part.
When an item in the list is clicked I inflate the detail-fragment into the main-content part and it all works well.
On the detail-screen I want the Action-Bar to display an up-button that goes back to the list-screen.
Considering the fact that I am using fragments, rather than separate activites, how can I achieve that?
You can enable the up button each time the Detail Fragment loads, and disable it whenever any of the other Fragments load.
First define these methods in your Activity, which you can call from the Fragments in order to show/hide the up button:
public void showUpButton() {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public void hideUpButton() {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
}
You will probably want to just enable the up button in on Resume() of the detail Fragment (MainActivity is just an example, change to the name of your Activity) .....
#Override
public void onResume() {
super.onResume();
MainActivity activity = (MainActivity)getActivity();
if (activity != null) {
activity.showUpButton();
}
}
Then in the other Fragments:
#Override
public void onResume() {
super.onResume();
MainActivity activity = (MainActivity)getActivity();
if (activity != null) {
activity.hideUpButton();
}
}
The next thing is to make the up button actually go back. First ensure that you're adding the Fragment with the up button to the back stack, and then add this to that Fragment.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
((MainActivity)getActivity()).onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Then in the Activity, override onBackPressed() and pop from the back stack if the FragmentManager has any entries:
#Override
public void onBackPressed() {
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 1) {
fragmentManager.popBackStackImmediate();
} else {
super.onBackPressed();
}
}
I've got an app with nav drawer, which is switching fragments. From inside one of those fragments, I am calling a new activity. When I click back in this activity (in toolbar), I want to go back to previous selected fragment but instead it puts me back to first fragment. I am adding my fragment to back stack so this should not be a problem.
Here is what I have already tried:
I have overriden the onBackPressed method in my 2nd activity like this:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
} else {
getFragmentManager().popBackStack();
}
}
It is not working. I also saved index of current fragment inside onsaveinstancestate method and retrieve it but same result. I also tried with always putting current fragment inside variable and try to reshow it but still, it does not work. Anything else I could try?
Fun fact: if I press back inside bottom panel, it does actually goes back to previous fragment.
EDIT: Here is my code for doing this:
private void replaceFragment(Fragment fragment)
{
if (fragment != null)
{
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction()
.replace(R.id.main_content, fragment)
.addToBackStack(null)
.commit();
}
}
I add first fragment only, if savedInstanceState is null, like so:
if (savedInstanceState == null) {
// first time
mTitle = getResources().getString(R.string.home);
replaceFragment(HomeFragment.newInstance());
}
And yes, all this is done inside onCreate() method.
I had the same problem and got fixed. The only thing you need to do is to
override the method "onOptionsItemSelected" in the activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
android.R.id.home is your first fragment in the menu.
What I tend to do is this
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
} else {
super.onBackPressed(); //replaced
}
}
This way it handles the fragment stuff on its own within, but when there's no fragments left to go back to, then it finishes the activity.
EDIT: UP navigation can recreate your previous activity even if it already exists. To prevent that from happening, redefine the Up navigation's event in onOptionsItemSelected like so:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent parentIntent = NavUtils.getParentActivityIntent(this);
if(parentIntent == null) {
finish();
return true;
} else {
parentIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(parentIntent);
finish();
return true;
}
}
return super.onOptionsItemSelected(item);
}
When you call an activity from other activity's fragment, then the previous activity's instance state that is the calling activity which was having fragment's instance state will be saved in stack...so all u need to do is finish the called activity and u will have the fragment from which you called your second activity.
#Override
public void onBackPressed() {
finish();
}
Try
getFragmentManager().popBackStackImmediate();
It worked for me.
Sorry, I don't have enough reputation to leave a comment. So I have to guess. I once had the same issue.
Sounds like a problem related to the activity lifecycle (http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle). Be sure to add your first fragment only once, because your activity's fragment manager is capable of the lifecycle.
Thus, the statement that adds the first fragment to your fragment manager should be surrounded by if (savedInstanceState == null) { ... }.
I see, that people are still trying to help me. This answer helped me fix my problem: Android - Navigation Up from Activity to Fragment
Override onOptionsItemSelected method in activity as follows,
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
When you call new Activity from Fragment you should write :
Intent intent = new Intent(getFragment().getContext(),NewActivity.class);
getFragment().getContext().startActivity(intent);
FragmentManager fm = CurrentFragment.getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.addToBackStack(CurrentFragment.class.getName()).commit();
fm.executePendingTransactions();
It Works for me.
getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true)
.addToBackStack("home") // should not be null
.replace(binding.fragmentContainer.getId(), new HomeFragment())
.commit();
Pass name in addToBackStack(String name) method. This function add fragment into backstack if passed name is not null. App automatically start managing backstack of fragment
Remove your override onBackPressed() method. No use of it now
I'm working on an app that need Navigation Drawer. This app has 1 MainActivity and about 10 fragments on it. When I click the Navigation Drawer icon in MainActivity it will show the 10 fragments so I can select each of them.
I choose fragment A, then B, then C...to F, for example. When I'm in fragment F and press the Back button, it will take me back to fragment E, then Back again it will take me to fragment D...
My problem is when I'm back to fragment A (from fragment B, of course) and press Back button one more time, it take me to a blank white screen (I think this is the main activity layout). And press Back one more time, the app will exit.
What I want is when I'm back to fragment A (last fragment) and hit Back, the app will exit immediately, not the blank white screen anymore
I've search on SO and found 1 similar question but no answer yet so I have to make another question
How can I do this?
Thank you very much
just exit the app at second last screen
public void onBackPressed() {
if (manager.getBackStackEntryCount() > 1 ) {
// If there are back-stack entries, leave the FragmentActivity
// implementation take care of them.
manager.popBackStack();
} else {
// Otherwise, ask user if he wants to leave :)
new AlertDialog.Builder(this)
.setTitle("Really Exit?")
.setMessage("Are you sure you want to exit?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
MainActivity.super.onBackPressed();
}
}).create().show();
}
}
Remove addToBackStack() from your Fragment A.
Hope that helps.
I guess I am the one with the other unanswered question, so I want to show you my workaround:
I check if there is one child in my FrameLayout. If there is one, I will go one fragment back. And check again. Because I do only know the whitescreen for sure, I need to check after it for 0 childs left. If there exist still another fragment, there is nothing to do anymore, but if childs == 0, you want to ask for leaving the activity.
Alternatively you can remove the AlertDialog and close the app if you reach this last fragment.
#Override
public void onBackPressed() {
FrameLayout fl = (FrameLayout) findViewById(R.id.content_frame);
if (fl.getChildCount() == 1) {
super.onBackPressed();
if (fl.getChildCount() == 0) {
new AlertDialog.Builder(this)
.setTitle("Close App?")
.setMessage("Do you really want to close this beautiful app?")
.setPositiveButton("YES",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
finish();
}
})
.setNegativeButton("NO",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
}
}).show();
// load your first Fragment here
}
} else if (fl.getChildCount() == 0) {
// load your first Fragment here
} else {
super.onBackPressed();
}
}
I just fixed my similar issue. I adapted Ali Azhar's solution. Since I have a splash screen activity, I didn't want to terminate the app, otherwise when I try to resume the app (pressing the active apps button on the phone and selecting the app), the app would get stuck in the splash screen without proceeding to my main activity. So instead of
MainActivity.super.onBackPressed();
I used this:
moveTaskToBack(true);
to show the home screen. I didn't need any exit confirmation by the user, so I removed the dialog code. I also wanted to adjust my replaceFragment(targetFragment, fragmentNameInBackStack) method to avoid adding the fragment to the backstack if it is the first fragment, but it turned out that there is no need to do that because we make the manager pop from the backstack if the are more than one fragment in the backstack, so if there is only one fragment, that's fine, we quit. It's good because I wanted to retain my back navigation behavior between different screens/fragments. So here is the code:
#Override
public void onBackPressed() {
FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 1 ) {
manager.popBackStack();
} else {
// if there is only one entry in the backstack, show the home screen
moveTaskToBack(true);
}
}
It's Easy way to exit your app just paste below code
#Override
public void onBackPressed() {
FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 1) {
// If there are back-stack entries, leave the FragmentActivity
// implementation take care of them.
manager.popBackStack();
} else {
// Otherwise, ask user if he wants to leave :)
new AlertDialog.Builder(this)
.setTitle("Really Exit?")
.setMessage("Are you sure you want to exit?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
// MainActivity.super.onBackPressed();
finish();
moveTaskToBack(true);
}
}).create().show();
}
Very late answer. But I hope atleast help this answer anyone.
With help of following code I implement the double back press exit (It give Toast "Please click back again to exit" if press once more only app will exit.)
getBackStackEntryCount() - give the current count of your back stack fragments.
int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
if this value==0 no fragments avilable in back stack. so execute the double back press exit code.
else allow the backpress action using super.onBackPressed();
#Override
public void onBackPressed() {
int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
//backStackEntryCount==0 -> no fragments more.. so close the activity with warning
if (backStackEntryCount == 0){
if (homePressed) {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Please click back again to exit", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce = false;
}
}, 2000);
} else {
homePressed = true;
}
}
//some fragments are there.. so allow the back press action
else {
super.onBackPressed();
}
}
Globally declare these variables
boolean homePressed = true, doubleBackToExitPressedOnce = false;
Use this.. Easy solution but works perfectly for me. This closes the application after you hit the last open fragment.
#Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount() == 1) {
moveTaskToBack(false);
}
else {
super.onBackPressed();
}
}
In onBack method check no of fragments available in the with fragment manager... If its of its 1 then close the application using move taskback method
I guess you can either avoid the back button press or finish the activity on back button pressed.Generally if you are using Navigation Drawer than this would not be the problem at all but you can try.
#Override
public void onBackPressed()
{
// Do Here what ever you want do on back press;
}
or you can go for Navigation Drawer
http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
This is what that worked for me.
If called from MainActivity
supportFinishAfterTransition();
If called from fragment
getActivity().supportFinishAfterTransition();
This one worked for me (Exit double click to exit from Fragment)
int backButtonCount = 0;
#SuppressLint({"ResourceAsColor", "ResourceType"})
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
//binding fragment view
view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener((v, keyCode, event) -> {
Log.i("Fragment_Home", "keyCode: " + keyCode);
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
Log.e(TAG, "onCreateView: " + "Fragment Hom Key up");
if (backButtonCount >= 1) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
getActivity().finish();
} else {
Toast.makeText(getContext(), "Please click BACK again to exit", Toast.LENGTH_SHORT).show();
backButtonCount++;
new Handler().postDelayed(() -> {
backButtonCount = 0;
}, 2000);
}
I have only one activity and multiple fragments in my application.
Two main fragment A(left) and B(right).
Fragment A1 called from A
B1 called from B
B2 called from B1
All fragments have individual back buttons.
So when I press back button of fragment A1, it should go back to A, similarly when Back button from B2 is pressed, B1 appears and from B1 to B and so on.
How to implement this type of functionality?
public void onBackPressed()
{
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.popBackStack();
}
I have implemented the similar Scenario just now.
Activity 'A' -> Calls a Fragment 'A1' and clicking on the menu item, it calls the Fragment 'A2' and if the user presses back button from 'A2', this goes back to 'A1' and if the user presses back from 'A1' after that, it finishes the Activity 'A' and goes back.
See the Following Code:
Activity 'A' - OnCreate() Method:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activityA);
if (savedInstanceState == null) {
Fragment fragInstance;
//Calling the Fragment newInstance Static method
fragInstance = FragmentA1.newInstance();
getFragmentManager().beginTransaction()
.add(R.id.container, fragInstance)
.commit();
}
}
Fragment : 'A1'
I am replacing the existing fragment with the new Fragment when the menu item click action happens:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_edit_columns) {
//Open the Fragment A2 and add this to backstack
Fragment fragment = FragmentA2.newInstance();
this.getFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack(null)
.commit();
return true;
}
return super.onOptionsItemSelected(item);
}
Activity 'A' - onBackPressed() Method:
Since all the fragments have one parent Activity (which is 'A'), the onBackPressed() method lets you to pop fragments if any are there or just return to previous Activity.
#Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
}
else {
getFragmentManager().popBackStack();
}
}
If you are looking for Embedding Fragments inside Fragments, please refer the link: http://developer.android.com/about/versions/android-4.2.html#NestedFragments
#trueblue's answer got me going with one minor but annoying issue. When there is only one fragment on the backstack and you press back button, that frame is removed and the app remains active with a blank screen. User needed to press back button one more time to exit the app. I modified the original code to the following in order to handle this situation
#Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
}
else if(getFragmentManager().getBackStackEntryCount() == 1) {
moveTaskToBack(false);
}
else {
getFragmentManager().popBackStack();
}
}
When there is only 1 fragment in the backstack, we are basically telling android to move the whole app to back.
Update (and probably a better answer)
So after doing some more reading around this, I found out that you can add fragment manager transactions to back stack and then android handles back presses automatically and in a desired way. The below code snippet shows how to do that
Fragment fragment; //Create and instance of your fragment class here
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment).addToBackStack(null);
fragmentTransaction.commit();
fragmentTransaction.addToBackStack(null);
The last line shows how you add a transaction to back stack. This solves back press issue for fragments in most situations except for one. If you go on pressing back button, then eventually you will reach a point when there is only one fragment in the back stack. At this point, you will want to do one of the two things
Remove the activity housing the fragment from the back stack of the task in which activity is running. This is because you do not want to end up with a blank activity
If the activity is the only activity in the back stack of the task, then push the task in background.
In my case, it was the later, so I modified the overridden onBackPressed method from my previous answer to look like below
#Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 1) {
moveTaskToBack(false);
}
else {
super.onBackPressed();
}
}
This code is simpler because it has less logic and it relies on framework than on our custom code. Unfortunately I did not manage to implement code for first situation as I did not need to.
You have to implement your own backstack implementation as explained here.
You can call the popFragments() whenever you click the back button in a fragment and call pushFragments() whenever you navigate from one Fragment to other.
Just Do
getActivity().getFragmentManager().popBackStack();
Try this, Its Work for me.
public void onBackPressed() {
if (mainLayout.isMenuShown()) {
mainLayout.toggleMenu();
} else {
FragmentManager fm = getSupportFragmentManager();
Log.print("back stack entry", fm.getBackStackEntryCount() + "");
if (fm.getBackStackEntryCount() > 1) {
fm.popBackStack();
// super.onBackPressed();
// return;
} else {
if (doubleBackToExitPressedOnce) {
fm.popBackStack();
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Press one more time to exit",
Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce = false;
}
}, 3000);
}
}
}
Back button will traverse in the order, in which Fragments were added to backstack. This is provided as a navigation function by default. Now if you want to go to specific Fragment, you can show it from backstack.
You can handle it by adding tag in the backStack. Check my answer here :
https://stackoverflow.com/a/19477957/1572408
hope it helps
#Override
public void onResume() {
super.onResume();
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
// replace your fragment here
return true;
}
return false;
}
});
}
// Happy Coding
If you press back image you have to create method first like this
private void Backpresses() {
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.contant_main, new Home()).commit();
}
then you have to call like this when you press back image..
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Backpresses();
}
});
It work fine for me.