Reputation: 3509
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
Upvotes: 12
Views: 18496
Reputation: 1591
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);
}
Upvotes: 0
Reputation: 73
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();
}
}
Upvotes: 1
Reputation: 18356
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;
Upvotes: 1
Reputation: 2132
This is what that worked for me.
If called from MainActivity
supportFinishAfterTransition();
If called from fragment
getActivity().supportFinishAfterTransition();
Upvotes: 0
Reputation: 8047
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();
}
Upvotes: 1
Reputation: 6016
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);
}
}
Upvotes: 4
Reputation: 1803
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();
}
}
Upvotes: 12
Reputation: 114
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();
}
}
Upvotes: 6
Reputation: 1
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/
Upvotes: 0
Reputation: 3874
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
Upvotes: 0