How to use getActionBar()/getSupportActionBar() when using material theme and AppCompat

17,880

Add to your activity xml layout code below:

<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/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    />

It will add actionbar where you want.

In your activity onCreate

Write this:

toolbar = (Toolbar) findViewById(R.id.toolbar);

        if (toolbar != null)
        {
            setSupportActionBar(toolbar);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setElevation(0); // or other
        }

And use only getSupportActionBar / setSupportActionBar

Your activity should extend ActionBarActivity

In your app theme add:

<item name="windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>

It should work perfectly.

And one more thing - you can use AppCompat theme on Lollipop too. On Lollipop AppCompat theme is extending Material theme so... they are doing it for you ;-)

Check how Google guys achieve that in Google IO app: https://github.com/google/iosched/tree/master/android/src/main/res

Share:
17,880
DevWithZachary
Author by

DevWithZachary

Sr Android Developer Advocate @Vonage

Updated on June 13, 2022

Comments

  • DevWithZachary
    DevWithZachary almost 2 years

    My application returns null on getActionBar() with android 4.4 and below, from research so I can see this is because my app is using a material theme for Android 5 and AppCompat for older versions.

    However I cant see to fix the return null issue, or get getSupportActionBar() working, below is my code, what needs changing so that I can use getActionBar/getSUpportActionBar on older android but still use material theme on 5.

    My Activity:

    public class MapsActivity extends ActionBarActivity implements LocationListener {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_maps);
            ...
            mDrawerLayout.setDrawerListener(mDrawerToggle);
    
            toolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
    
        if (toolbar != null)
        {
            setSupportActionBar(toolbar);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setHomeButtonEnabled(true);
            getSupportActionBar().setElevation(0); // or other
        }
    
            ...
        }
    ...
    }
    

    v21/style.xml

        <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- your app's theme inherits from the Material theme -->
        <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
            <item name="windowActionBar">false</item>
            <item name="android:windowNoTitle">true</item>
            <!-- Main theme colors -->
            <!--   your app branding color for the app bar -->
            <item name="android:colorPrimary">@color/primary</item>
            <!--   darker variant for the status bar and contextual app bars -->
            <item name="android:colorPrimaryDark">@color/primary_dark</item>
            <item name="android:navigationBarColor">@color/primary</item>
    
            <!--   theme UI controls like checkboxes and text fields -->
            <item name="android:colorAccent">@color/accent</item>
        </style>
    </resources>
    

    style.xml

    <resources>
    
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowActionBar">false</item>
        <item name="android:windowNoTitle">true</item>
    </style>
    
    </resources>
    

    gradle dependency

    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:21.0.+'
        compile 'com.google.android.gms:play-services:6.5.87'
        compile 'com.android.support:appcompat-v7:21.0.3'
    }
    

    my XML layout (after changes made by answer)

    RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <include
        android:id="@+id/toolbar_actionbar"
        layout="@layout/toolbar_default"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    
    <android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content view -->
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            </RelativeLayout>
    
    <!-- The navigation drawer -->
    <RelativeLayout
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#111">s
    
    
        </RelativeLayout>
    
    </android.support.v4.widget.DrawerLayout>
    </RelativeLayout>
    

    toolbar_default.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.Toolbar
        style="@style/ToolBarStyle"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="@dimen/abc_action_bar_default_height_material"/>
    

    ToolBarStyle.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources><style name="ToolBarStyle" parent="">
        <item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
        <item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
    </style></resources>
    

    Error below answer gives:

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.zpwebsites.whatsintown/com.zpwebsites.whatsintown.MapsActivity}: android.view.InflateException: Binary XML file line #1: Error inflating class android.support.v7.widget.Toolbar
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
                at android.app.ActivityThread.access$800(ActivityThread.java:144)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:135)
                at android.app.ActivityThread.main(ActivityThread.java:5221)
                at java.lang.reflect.Method.invoke(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:372)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
         Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class android.support.v7.widget.Toolbar
                at android.view.LayoutInflater.createView(LayoutInflater.java:633)
                at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:482)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
                at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(ActionBarActivityDelegateBase.java:228)
                at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:102)
                at com.zpwebsites.whatsintown.MapsActivity.onCreate(MapsActivity.java:80)
                at android.app.Activity.performCreate(Activity.java:5933)
                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
                at android.app.ActivityThread.access$800(ActivityThread.java:144)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:135)
                at android.app.ActivityThread.main(ActivityThread.java:5221)
                at java.lang.reflect.Method.invoke(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:372)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
         Caused by: java.lang.reflect.InvocationTargetException
                at java.lang.reflect.Constructor.newInstance(Native Method)
                at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
                at android.view.LayoutInflater.createView(LayoutInflater.java:607)
                at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:482)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
                at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(ActionBarActivityDelegateBase.java:228)
                at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:102)
                at com.zpwebsites.whatsintown.MapsActivity.onCreate(MapsActivity.java:80)
                at android.app.Activity.performCreate(Activity.java:5933)
                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
                at android.app.ActivityThread.access$800(ActivityThread.java:144)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:135)
                at android.app.ActivityThread.main(ActivityThread.java:5221)
                at java.lang.reflect.Method.invoke(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:372)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
         Caused by: java.lang.RuntimeException: Failed to resolve attribute at index 13
                at android.content.res.TypedArray.getDrawable(TypedArray.java:747)
                at android.view.View.<init>(View.java:3730)
                at android.view.ViewGroup.<init>(ViewGroup.java:491)
                at android.view.ViewGroup.<init>(ViewGroup.java:487)
                at android.support.v7.widget.Toolbar.<init>(Toolbar.java:195)
                at android.support.v7.widget.Toolbar.<init>(Toolbar.java:191)
                at java.lang.reflect.Constructor.newInstance(Native Method)
                at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
                at android.view.LayoutInflater.createView(LayoutInflater.java:607)
                at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:482)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
                at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(ActionBarActivityDelegateBase.java:228)
                at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:102)
                at com.zpwebsites.whatsintown.MapsActivity.onCreate(MapsActivity.java:80)
                at android.app.Activity.performCreate(Activity.java:5933)
                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
                at android.app.ActivityThread.access$800(ActivityThread.java:144)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:135)
                at android.app.ActivityThread.main(ActivityThread.java:5221)
                at java.lang.reflect.Method.invoke(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:372)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
    
  • DevWithZachary
    DevWithZachary about 9 years
    after changing my xml I get and error when running the app (xml and error above)
  • radzio
    radzio about 9 years
    You have placed toolbar in wrong place. Check this tutorial antonioleiva.com/material-design-everywhere
  • DevWithZachary
    DevWithZachary about 9 years
    have updated to show current code but still not working
  • radzio
    radzio about 9 years
    @ZacPowell you have wrong xml layout for met. DrawerLayout should be root of your view if you want to achieve 'standard' actvity with navigation drawer.