6

I have six Tabs in MainActivity, the second tab have a listview, when user press on the listview item, its open a new Activity with Action bar, so, when user press on the back button of the second activity, I want to go to previous tab (second tab) of Main Activity, but its loading the First Tab (Home Tab).

How I can resolve this problem?

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
Able Alias
  • 3,824
  • 11
  • 58
  • 87
  • It should work in normal way,I have an app with same structure it is working fine,What is inside tabs fragments ..?,Can you please explain that too – Saleeh Jul 30 '14 at 06:15
  • 1
    If I'm press the device back button it will come to previous tab, but when I press Action bar back button its recreating the Activity – Able Alias Jul 30 '14 at 08:29

2 Answers2

10

Using the Up navigation to return to the parent activity recreates the parent activity. When the parent activity is recreated you lose your selected tab. Rather than saving the selected tab, it is easier to just not recreate the parent activity. This can be done by adding the following line to the parent activity section of your AndroidManifest file.

android:launchMode="singleTop"

This will prevent the parent from being recreated and thus your previously selected tab will still be in the same state.

For example, if the MainActivity is the parent with the tabs, then the manifest would look something like this:

<activity android:name=".MainActivity"
          android:launchMode="singleTop">
    ...
</activity>

See also:

Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • I discovered the `lauchMode` flags after having written my answer above. And I agree this is the best way with some caveats (http://stackoverflow.com/questions/19039189/intent-if-activity-is-running-bring-it-to-front-else-start-a-new-one-from-n/36150120#36150120). So +1, and this should be the accepted answer! – Shlublu Jan 18 '17 at 07:49
7

We have three cases here. The actual back button (regardless it is hardware or software), the Action Bar's parent ("Up") button, and both buttons:

  • Back button case:

When you call the SecondActivity, use startActivityForResult() to keep MainActivity informed of the SecondActivity's lifecycle. When "back" is pressed, capture this event in MainActivity.onActivityResult() and switch to the second tab:

MainActivity: where you currently start your activity:

// Start SecondActivity that way. REQUEST_CODE_SECONDACTIVITY is a code you define to identify your request
startActivityForResult(new Intent(this, SecondActivity.class), REQUEST_CODE_SECONDACTIVITY);

MainActivity: onActivityResult():

// And this is how you handle its result    
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if (requestCode == REQUEST_CODE_SECONDACTIVITY && resultCode == RESULT_CANCEL) {
        switchToTab(2); // switch to tab2 
    }
    // else... other cases
}
  • Action Bar's "Up" button case:

If this behaviour has to be connected to the Action Bar's "Up" button instead of the back button, you have to override getSupportParentActivityIntent() or getParentActivityIntent() depending on whether you are using the support library or not.

SecondActivity: get[Support]ParentActivityIntent():

@Override 
public Intent getSupportParentActivityIntent() { // getParentActivityIntent() if you are not using the Support Library
    final Bundle bundle = new Bundle();
    final Intent intent = new Intent(this, MainActivity.class);

    bundle.putString(SWITCH_TAB, TAB_SECOND); // Both constants are defined in your code
    intent.putExtras(bundle);

    return intent;
} 

And then, you can handle this in MainActivity.onCreate().

MainActivity: onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {

    ...

    final Intent intent = getIntent();

    if (intent.hasExtra(SWITCH_TAB)) {
        final int tab = intent.getExtras().getInt(SWITCH_TAB);

        switchToTab(tab); // switch to tab2 in this example
    }

    ...
  • Both buttons case:

Should you wish to handle both buttons the same way (regardless this is a good idea or not, I just don't know), both solutions above can be implemented concurrently with no problem.

Side note: to determine whether this is a good idea or not, this official guide may help. Especially the section "Navigating Up with the App Icon".

Shlublu
  • 10,917
  • 4
  • 51
  • 70
  • onActivityResult event wont trigger when press ActionBar Back button – Able Alias Jul 30 '14 at 08:28
  • No, the above is valid for the back button. If you youse the ActionBar's parent (not back) button, you'll have to override `Intent getSupportParentActivityIntent()` if you are using the Support action bar, and `getParentActivityIntent()` otherwise. Playing with the Intent's extras allow you to do a similar thing. – Shlublu Jul 30 '14 at 08:49
  • I'm using "android:parentActivityName" in manifest to get the back button in activity, but when click on action bar back button onActivityResult not triggering. – Able Alias Jul 30 '14 at 09:00
  • This is because "android:parentActivityName" is not tied to the back but the "Up" button. The behaviour is different. I have edited my answer accordingly. – Shlublu Jul 30 '14 at 09:05
  • Yes, the getParentActivityIntent with extras works well, but I have a question, when device back button press, the MainActivity not creating again just resume it, but when click ActionBar parent button click the MainActivity creating again, do you know why? – Able Alias Jul 30 '14 at 09:19
  • I think this is to allow navigating "back". Really back I mean. Should you don't like this behaviour, you can override `getSupportParentActivityIntent()` if a way it does `{ finish(); return null; }`. This will switch back to the calling activity without recreating it. But I don't know whether we can use `setResult()` this way, I never tried. (And I am not sure this would be a safe guaranteed behaviour should it works). – Shlublu Jul 30 '14 at 09:24
  • Actually, I'm looking the same behavior of device back button in Action Bar parent click, but the getSupportParentActivityIntent() event also recreating the MainActivity – Able Alias Jul 30 '14 at 09:31
  • Even if you return `null` after having called `finish()`? Shouldn't be the case. – Shlublu Jul 30 '14 at 09:33
  • yes, this is I want... @Override public Intent getParentActivityIntent() { this.finish(); return null; } – Able Alias Jul 30 '14 at 09:39
  • I think this is a good solution. I had no idea that getSupportParentActivityIntent existed :-) Had it working in no time. Up-voting. – Dimitar Vukman Jan 17 '17 at 13:00