52

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 Show up/back button on android nested PreferenceScreen?, 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>
Community
  • 1
  • 1
Gavriel
  • 18,880
  • 12
  • 68
  • 105

7 Answers7

62

@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);
        }
    }
}
Gavriel
  • 18,880
  • 12
  • 68
  • 105
  • 1
    Keep in mind that, for `NavUtils.navigateUpFromSameTask` to work, you need to declare in your child activity (in this case, the `SettingsActivity`) tag in the manifest the appropriate parent activity, ie. `android:parentActivityName="com.example.myfirstapp.MainActivity"`. – Joao Sousa Mar 07 '15 at 11:39
  • 1
    Is it required to add `NavUtils.navigateUpFromSameTask(SettingsActivity.this); `? I only called the `actionbar.setNavigationIcon();` and going back mechanism is working – Sudara Mar 28 '15 at 10:17
  • 1
    @S_Madushan Yes it is not required if you have declared parent activity in `Manifest` – Tomasz Mularczyk Jun 22 '15 at 14:37
31

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"
        />
ls.illarionov
  • 741
  • 1
  • 10
  • 12
  • 1
    While not a complete answer, this is a great update to @Gavriel 's answer – tir38 Jun 30 '16 at 20:20
  • `app:navigationContentDescription="..."` can be used to set the content description to, for example, "Navigate up" – darnmason Dec 21 '16 at 05:31
  • 1
    @darnmason can we handle click event for the `?homeAsUpIndicator` in the xaml template? – Nick King Sep 26 '17 at 14:06
  • If you use databinding, you can use `binding:navigationOnClickListener="@{() -> viewModel.onBackNavClicked()}"`. Databinding finds the setters for unspecified properties automatically. – Saad Farooq Nov 17 '17 at 00:00
12

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

Aniruddha K.M
  • 7,361
  • 3
  • 43
  • 52
  • This is about standalone toolbars, not the ones set as actionbar – mhenryk Oct 06 '16 at 10:21
  • I set actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayShowHomeEnabled(true); . It is working fine. I have a textview in toolbar which displays title. I put textview as center. If I won't enable back arrow then textivew coming in center. If I enable back arrow it is not coming in center. I have tried a lot. Not able to find the solution. – Prashanth Debbadwar Nov 18 '16 at 06:14
  • Share your code, probably some layout issue will check and tell – Aniruddha K.M Nov 18 '16 at 06:16
7

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>
Tomasz Mularczyk
  • 34,501
  • 19
  • 112
  • 166
  • `getSupportActionBar().setDisplayHomeAsUpEnabled(true);` `getSupportActionBar().setHomeButtonEnabled(true);` – Mussa Jan 26 '16 at 02:42
2

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

NavUtils.navigateUpFromSameTask(SettingsActivity.this); 
Viktor Yakunin
  • 2,927
  • 3
  • 24
  • 39
2

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">

    .....
Stéphane
  • 161
  • 1
  • 6
0

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

Alpha Huang
  • 1,297
  • 1
  • 12
  • 15