149

I have an activity with a listview. When the user click the item, the item "viewer" opens:

List1.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {

        Intent nextScreen = new Intent(context,ServicesViewActivity.class);
        String[] Service = (String[])List1.getItemAtPosition(arg2);

        //Sending data to another Activity
        nextScreen.putExtra("data", datainfo);
        startActivityForResult(nextScreen,0);
        overridePendingTransition(R.anim.right_enter, R.anim.left_exit);
    }
});

This works fine, but on the actionbar the back arrow next to the app icon doesn't get activated. Am I missing something?

Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
Joaolvcm
  • 1,983
  • 3
  • 20
  • 24
  • 66
    `getActionBar().setDisplayHomeAsUpEnabled(true);` in onCreate and `switch (item.getItemId()) {case android.R.id.home: onBackPressed();break;}` in `onOptionsItemSelected` ? both in ServicesViewActivity – Selvin Apr 11 '12 at 15:25
  • 8
    Why not as an answer shelving? – KarlKarlsom Apr 11 '12 at 16:39

14 Answers14

282

Selvin already posted the right answer. Here, the solution in pretty code:

public class ServicesViewActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // etc...
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }
}

The function NavUtils.navigateUpFromSameTask(this) requires you to define the parent activity in the AndroidManifest.xml file

<activity android:name="com.example.ServicesViewActivity" >
    <meta-data
     android:name="android.support.PARENT_ACTIVITY"
     android:value="com.example.ParentActivity" />
</activity>

See here for further reading.

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Michael Klenk
  • 3,202
  • 2
  • 19
  • 19
  • 1
    In my situation I was looking for a way to not call onCreate of the parent when returning to it. To do this, I used your implementation, but called finish() instead of NavUtils.navigateUpFromSameTask(this). finish() calls my onStart instead of onCreate which was more ideal for me. – Jon Apr 28 '16 at 05:58
  • Setting meta-data in manifest is a key to make navigation button working – VSB Jul 27 '16 at 11:13
  • Use `getActionBar().setDisplayHomeAsUpEnabled(true);` incase you are using support libraries. – Abhinav Upadhyay Aug 20 '18 at 12:56
  • How do you change the direction of the "wipe"? By default, implementing this back navigation sweeps the screen from right to left, and it looks like it's loading a new screen. However, I want it to wipe from left to right, just like hitting the device own back key. – stingray_ Sep 06 '18 at 22:14
  • 1
    I got the error: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference – Jones Mar 15 '20 at 21:12
  • use this ```getSupportActionBar().setDisplayHomeAsUpEnabled(true);``` and ```onBackPressed()``` inside ```onSupportNavigateUp()``` – Ganesh MB Mar 15 '21 at 11:58
187

Make sure your the ActionBar Home Button is enabled in the Activity:

Android, API 5+:

@Override
public void onBackPressed() {
     ...
     super.onBackPressed();
}

ActionBarSherlock and App-Compat, API 7+:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    ...
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

Android, API 11+:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    ...
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

Example MainActivity that extends ActionBarActivity:

public class MainActivity extends ActionBarActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Back button
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home: 
            // API 5+ solution
            onBackPressed();
            return true;

        default:
            return super.onOptionsItemSelected(item);
        }
    }
}

This way all the activities you want can have the backpress.

Android, API 16+:

http://developer.android.com/training/implementing-navigation/ancestral.html

AndroidManifest.xml:

<application ... >
    ...
    <!-- The main/home activity (it has no parent activity) -->
    <activity
        android:name="com.example.myfirstapp.MainActivity" ...>
        ...
    </activity>
    <!-- A child of the main activity -->
    <activity
        android:name="com.example.myfirstapp.DisplayMessageActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName="com.example.myfirstapp.MainActivity" >
        <!-- The meta-data element is needed for versions lower than 4.1 -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />
    </activity>
</application>

Example MainActivity that extends ActionBarActivity:

public class MainActivity extends ActionBarActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Back button
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        // Respond to the action bar's Up/Home button
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
  • It's working for me when I change getSupportActionBar().setDisplayHomeAsUpEnabled(true); in to getActionBar().setDisplayHomeAsUpEnabled(true); and added these @SuppressLint("NewApi") at onCreate method inside and outsideFor REF : => http://developer.android.com/training/implementing-navigation/ancestral.html – gnganapath Feb 13 '15 at 06:28
  • 1
    @ganpath Careful, using getActionBar is for **API 11+**. – Jared Burrows Feb 13 '15 at 06:28
23

To enable the ActionBar back button you obviously need an ActionBar in your Activity. This is set by the theme you are using. You can set the theme for your Activity in the AndroidManfiest.xml. If you are using e.g the @android:style/Theme.NoTitleBar theme, you don't have an ActionBar. In this case the call to getActionBar() will return null. So make sure you have an ActionBar first.

The next step is to set the android:parentActivityName to the activity you want to navigate if you press the back button. This should be done in the AndroidManifest.xml too.

Now you can enable the back button in the onCreate method of your "child" activity.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

Now you should implement the logic for the back button. You simply override the onOptionsItemSelected method in your "child" activity and check for the id of the back button which is android.R.id.home.

Now you can fire the method NavUtils.navigateUpFromSameTask(this); BUT if you don't have specified the android:parentActivityName in you AndroidManifest.xml this will crash your app.

Sometimes this is what you want because it is reminding you that you forgot "something". So if you want to prevent this, you can check if your activity has a parent using the getParentActivityIntent() method. If this returns null, you don't have specified the parent.

In this case you can fire the onBackPressed() method that does basically the same as if the user would press the back button on the device. A good implementation that never crashes your app would be:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            if (getParentActivityIntent() == null) {
                Log.i(TAG, "You have forgotten to specify the parentActivityName in the AndroidManifest!");
                onBackPressed();
            } else {
                NavUtils.navigateUpFromSameTask(this);
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Please notice that the animation that the user sees is different between NavUtils.navigateUpFromSameTask(this); and onBackPressed().

It is up to you which road you take, but I found the solution helpful, especially if you use a base class for all of your activities.

dknaack
  • 60,192
  • 27
  • 155
  • 202
20

In the OnCreate method add this:

if (getSupportActionBar() != null) {
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

Then add this method:

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return true;
}
Marco Concas
  • 1,665
  • 20
  • 25
11

AndroidManifest file:

    <activity android:name=".activity.DetailsActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="br.com.halyson.materialdesign.activity.HomeActivity" />
    </activity>

add in DetailsActivity:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);   
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

it's work :]

Shaishab Roy
  • 16,335
  • 7
  • 50
  • 68
7

Android Annotations:

@OptionsItem(android.R.id.home)
void homeSelected() {
    onBackPressed();
}

Source: https://github.com/excilys/androidannotations

Community
  • 1
  • 1
ldd
  • 440
  • 5
  • 9
6

I think onSupportNavigateUp() is simplest and best way to do so

check the complete solution at the below stackoverflow answer. link: Click here for complete code

Inzimam Tariq IT
  • 6,548
  • 8
  • 42
  • 69
3

https://stackoverflow.com/a/46903870/4489222

To achieved this, there are simply two steps,

Step 1: Go to AndroidManifest.xml and in the add the parameter in tag - android:parentActivityName=".home.HomeActivity"

example :

 <activity
    android:name=".home.ActivityDetail"
    android:parentActivityName=".home.HomeActivity"
    android:screenOrientation="portrait" />

Step 2: in ActivityDetail add your action for previous page/activity

example :

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
      case android.R.id.home: 
          onBackPressed();
          return true;
   }
   return super.onOptionsItemSelected(item);}
}
Vivek Hande
  • 929
  • 9
  • 11
1

Following Steps are much enough to back button:

Step 1: This code should be in Manifest.xml

<activity android:name=".activity.ChildActivity"
        android:parentActivityName=".activity.ParentActivity"
        android:screenOrientation="portrait">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".activity.ParentActivity" /></activity>

Step 2: You won't give

finish();

in your Parent Activity while starting Child Activity.

Step 3: If you need to come back to Parent Activity from Child Activity, Then you just give this code for Child Activity.

startActivity(new Intent(ParentActivity.this, ChildActivity.class));
Kumar VL
  • 45
  • 4
1
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

in onCreated method for the new apis.

Kartik Garasia
  • 1,324
  • 1
  • 18
  • 27
1

If you are using Toolbar, I was facing the same issue. I solved by following these two steps

  1. In the AndroidManifest.xml
<activity android:name=".activity.SecondActivity" android:parentActivityName=".activity.MainActivity"/>
  1. In the SecondActivity, add these...
Toolbar toolbar = findViewById(R.id.second_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
MartenCatcher
  • 2,713
  • 8
  • 26
  • 39
1

Another option is to set the parentActivityName of the secondary activity to the MainActifity in your application Manifest file

<activity
        android:name=".ServiceViewActivity"
        android:parentActivityName=".MainActivity"/>
0

Building on Jared's answer, I had to enable and implement the action bar back button behavior in several activities and created this helper class to reduce code duplication.

public final class ActionBarHelper {
    public static void enableBackButton(AppCompatActivity context) {
        if(context == null) return;

        ActionBar actionBar = context.getSupportActionBar();
        if (actionBar == null) return;

        actionBar.setDisplayHomeAsUpEnabled(true);
    }
}

Usage in an activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    ActionBarHelper.enableBackButton(this);
}
datchung
  • 3,778
  • 1
  • 28
  • 29
0

I was trying this myself and one thing that worked for me:


        when(item.itemId) {
            R.id.action_signup -> signup() //other menu item
            android.R.id.home -> viewRoot.findNavController().navigateUp() //back 
        }

        return super.onOptionsItemSelected(item)
    }

I'm using a Jetpack navigation so that's the call to get the NavController.

RCB
  • 560
  • 4
  • 9