How to enable homeAsUp or call setDisplayHomeAsUpEnabled() on standalone toolbar with appcompat v21

AndroidAndroid AppcompatAndroid Actionbar-CompatAndroid Toolbar

Android Problem Overview


I am trying to convert my app to use the v21 AppCompat library, so I started to use Toolbar instead of ActionBar. In all my regular activities (which extend ActionBarActivity) everything is fine. but in my SettingsActivity which extends PreferenceActivity, and therefore I can't use the setSupportActionBar(actionbar) call I need to use a "standalone" toolbar. The toolbar shows up, but I can't figure out how could I add the "home / up" button to the toolbar.

SettingsActivity.java:

public class SettingsActivity extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);
        Toolbar actionbar = (Toolbar) findViewById(R.id.actionbar);
        if (null != actionbar) {

            // In every other activity that extends ActionBarActivity I simply use:
            // setSupportActionBar(actionbar);
            // final ActionBar supportActionBar = getSupportActionBar();
            // supportActionBar.setDisplayHomeAsUpEnabled(true);

            // but in PreferenceActivity you need to add a standalone toolbar:    
            actionbar.setTitle(R.string.title_activity_settings);
            actionbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    SettingsActivity.this.finish();
                }
            });

            // Inflate a menu to be displayed in the toolbar
            actionbar.inflateMenu(R.menu.settings);
        }
    }
}

layout/activity_settings.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              tools:context=".SettingsActivity"
              tools:menu="settings"
              tools:actionBarNavMode="standard"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <include
        layout="@layout/actionbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@android:id/list" />
</LinearLayout>

layout/actionbar.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/actionbar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimaryDark"
    app:theme="@style/AppTheme"
    />

menu/settings.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.fletech.android.redalert.SettingsActivity" >
</menu>

I tried to add actionBarStyle and displayOptions to my theme as explained in https://stackoverflow.com/questions/14190713/show-up-back-button-on-android-nested-preferencescreen/16247111, but in other places people said that actionBarStyle won't be used when I use Toolbar, and they seem to be right.

values/themes.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="AppTheme.Base"/>

    <style name="AppTheme.Base" parent="Theme.AppCompat">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimary</item>
        <item name="android:windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="windowActionModeOverlay">true</item>

        <!-- Set AppCompat’s actionBarStyle -->
        <item name="actionBarStyle">@style/MyActionBar</item>
    </style>

    <style name="MyActionBar" parent="Widget.AppCompat.ActionBar">
        <item name="displayOptions">showHome|homeAsUp|showTitle</item>
    </style>
<resources>

Android Solutions


Solution 1 - Android

@Pedro Oliveira's solution worked. I could even find the drawable that the AppCompat library uses (and therefore is already included in the apk). What more it's also mirrored, so it works both for ltr, rtl locales:

actionbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);

and this is it alltogether, with the correction from @VictorYakunin

public class SettingsActivity extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);
        Toolbar actionbar = (Toolbar) findViewById(R.id.actionbar);
        if (null != actionbar) {
            actionbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);

            actionbar.setTitle(R.string.title_activity_settings);
            actionbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    NavUtils.navigateUpFromSameTask(SettingsActivity.this);
                }
            });

            // Inflate a menu to be displayed in the toolbar
            actionbar.inflateMenu(R.menu.settings);
        }
    }
}

Solution 2 - Android

Yout can use ?homeAsUpIndicator instead of R.drawable.abc_ic_ab_back_mtrl_am_alpha:

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:navigationIcon="?homeAsUpIndicator"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:title="@string/title"
        />

Solution 3 - Android

way to late to the party here but i will still provide my 0.02$. i did it the following way to show the up arrow mark in fragment using AppCompactActivity

((MainActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);

and handle the onClick event inside your activity onOptionsItemSelected

Solution 4 - Android

If you provide parent activity name in Manifest.xml and meta-data to support Android 4.0 and lower then you can just set navigation icon (toolbar.setNavigationIcon(R.drawable.ic_action_back);) and it will work.

Manifest.xml example:

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".ProductActivity"
        android:label="@string/title_activity_product"
        android:parentActivityName=".MainActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".MainActivity" />
    </activity>

Solution 5 - Android

Thank you for the solution, the only point to add is that is better to use

NavUtils.navigateUpFromSameTask(SettingsActivity.this); 

Solution 6 - Android

Define a background 9patch for your toolbar ;) it's work. Here is toolbar_background.9.png

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/toolbar_background">

    .....

Solution 7 - Android

Try XML attribute android:navigationIcon, or app:navigationIcon for API older than 21.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGavrielView Question on Stackoverflow
Solution 1 - AndroidGavrielView Answer on Stackoverflow
Solution 2 - Androidls.illarionovView Answer on Stackoverflow
Solution 3 - AndroidMightianView Answer on Stackoverflow
Solution 4 - AndroidTomasz MularczykView Answer on Stackoverflow
Solution 5 - AndroidViktor YakuninView Answer on Stackoverflow
Solution 6 - AndroidStéphaneView Answer on Stackoverflow
Solution 7 - AndroidAlpha HuangView Answer on Stackoverflow