13

I'm using this template https://github.com/kanytu/android-material-drawer-template just to try out material design so I've implemented a few fragments some have webviews some have not.

My problem is when switching between the fragments I can see them being successfully added to the backstack

getFragmentManager().beginTransaction().replace(R.id.container, new FAQ()).addToBackStack("FAQ").commit();

But when I press the back button it just closes the app.

When I change it to use Activity instead of ActionBarActivity the navigation works fine but I lose some other functionality.

There is an override on the back button

@Override
public void onBackPressed() {
   if (mNavigationDrawerFragment.isDrawerOpen())
       mNavigationDrawerFragment.closeDrawer();
   else
       super.onBackPressed();
}

but even if that's removed it still happens. I think the problem lies somewhere in the super.onBackPressed

Is there any reason ActionBarActivity would break the back button?

Lachlan Goodhew-Cook
  • 1,101
  • 17
  • 31

2 Answers2

22

I recently read a post about this, sorry I can't find it anymore... But basically, it explained that the primary function of the back button is to finish the current Activity.

In fact, according to the onBackPressed() official documentation:

Called when the activity has detected the user's press of the back key. The default implementation simply finishes the current activity, but you can override this to do whatever you want.

And it would appear that even though the back button used to pop the backstack before 5.0, Google would have changed this behaviour with the new ActionBarActivity.

For my part, I used some workarround that works for me but that might not work for everybody, depending on your navigation implementation.

But in case it could be helpful to somebody, here it is :

@Override
public void onBackPressed()
{
    if (mDrawerLayout.isDrawerOpen()) {
        mDrawerLayout.closeDrawer();
    } else if (getFragmentManager().getBackStackEntryCount() > 0) {
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}

This way, ActionBarActivity.onBackPressed() is only called when the backstack is empty, in which case it destroys the ActionBarActivity.

MathieuMaree
  • 7,453
  • 6
  • 26
  • 31
  • 1
    This is somewhat frustrating behaviour! At least I feel like it. There is no documentation about a different behaviour of ActionBarActivity compared to Activity and there shouldnt be regarding basic elements like onBackPressed, right? How should developers know about these type of things except for investing hours of investigation on non-official android sites/blogs/posts etc.... :-/ @MathieuMaree If you could find the article you are writing about that would be terrific! – degill Feb 02 '15 at 22:28
  • @degill I just updated the answer, didn't find the post about it but I probably found it on the official documentation. I agree it's weird, but I guess the previous behaviour was a "mistake" and they decided to fix it in the `ActionBarActivity` (I'm just guessing). – MathieuMaree Feb 02 '15 at 23:58
  • 1
    Funny thing is that the actual implementation of onBackPressed in Activity actually pops the back stack while the implementation in ActionBarActivity finishes the Activity but the official docs state the opposite http://developer.android.com/reference/android/support/v7/app/ActionBarActivity.html#onBackPressed() – degill Feb 03 '15 at 06:57
  • And to be even further confused: using the v7 ActionBarActivity and after replacing some fragments but doing addToBackStack each time my activity is simply restarted when I press the back button...this is just nuts :-\ – degill Feb 03 '15 at 07:00
  • @degill Hmm yes it is indeed weird, although I don't feel like it's that big of a deal ;) – MathieuMaree Feb 03 '15 at 11:46
  • For a starting developer these kind of things can be more than annoying. A new developer might not even know where to look when something is misbehaving...but yeah, that's Android IMO :-) – degill Feb 03 '15 at 12:11
1

You should check "getFragmentManager" & "getSupportFragmentManager" is matched your activity & actionbaractivity or not.

Because, in Activity:

public void onBackPressed() {
    if (!mFragments.popBackStackImmediate()) {
        finish();
    }
}

in FragmentActivity:

public void onBackPressed() {
    if (!mFragments.popBackStackImmediate()) {
        finish();
    }
}

We can see the same code which already handled pop fragments backstatck. In my situation, I used actionbaractivity(extends FragmentAcvitiy), but I also used "getFragmentManager" , so I got the same error as you. After I have replaced "getFragmentManager" to "getSupportFragmentManager", that's ok! You also can replace "actionbaractiviy" to "Activity" to fix this problem.

Must ensure "getFragmentManager" match "Activity", "getSupportFragmentManager" match "FragmentActivity(ActionbarActivity)".

If you want add actionbar On API level 11 or higher, You can see below:

https://developer.android.com/guide/topics/ui/actionbar.html#Adding

On API level 11 or higher The action bar is included in all activities that use the Theme.Holo theme (or one of its descendants), which is the default theme when either the targetSdkVersion or minSdkVersion attribute is set to "11" or higher. If you don't want the action bar for an activity, set the activity theme to Theme.Holo.NoActionBar.

Lachlan Goodhew-Cook
  • 1,101
  • 17
  • 31
kmfish
  • 21
  • 4