105

I'm trying to recreate the look of Theme.AppCompat.Light.DarkActionBar with the new support library Toolbar.

If I choose Theme.AppCompat.Light my toolbar will be light and if I choose Theme.AppCompat it will be dark. (Technically you have to use the .NoActionBar version but as far as I can tell the only difference is

<style name="Theme.AppCompat.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="android:windowNoTitle">true</item>
</style>

Now there's no Theme.AppCompat.Light.DarkActionBar but naively I thought it'd be good enough to just make my own

<style name="Theme.AppCompat.Light.DarkActionBar.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="android:windowNoTitle">true</item>
</style>

However with this my toolbars are still Light themed. I've spent hours now trying different combinations of mixing the Dark (base) theme and the Light theme but I just can't find a combination that will let me have light backgrounds on everything but the toolbars.

Is there a way of getting the AppCompat.Light.DarkActionBar look with import android.support.v7.widget.Toolbar's?

Alex Bitek
  • 6,529
  • 5
  • 47
  • 77
Liminal
  • 1,709
  • 2
  • 12
  • 15

7 Answers7

218

The recommended way to style the Toolbar for a Light.DarkActionBar clone would be to use Theme.AppCompat.Light.DarkActionbar as parent/app theme and add the following attributes to the style to hide the default ActionBar:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

Then use the following as your Toolbar:

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>

For further modifications, you would create styles extending ThemeOverlay.AppCompat.Dark.ActionBar and ThemeOverlay.AppCompat.Light replacing the ones within AppBarLayout->android:theme and Toolbar->app:popupTheme. Also note that this will pick up your ?attr/colorPrimary if you have set it in your main style so you might get a different background color.

You will find a good example of this is in the current project template with an Empty Activity of Android Studio (1.4+).

oRRs
  • 2,292
  • 1
  • 12
  • 13
  • 1
    Well yes you can. "If you want to inherit from styles that you've defined yourself, you do not have to use the parent attribute. Instead, just prefix the name of the style you want to inherit to the name of your new style, separated by a period." http://developer.android.com/guide/topics/ui/themes.html#Inheritance – Liminal Oct 22 '14 at 09:22
  • Thanks, didn't know that. Still, the rest of my answer should solve your question. – oRRs Oct 22 '14 at 09:32
  • 1
    Also using the xml you posted I get a white toolbar with white text or if I change the theme to `ThemeOverlay.AppCompat.ActionBar` I get white toolbar with black text so it doesn't seem to work that well. Doesn't seem like the system cares about the `@color/background_material_dark` in `Base.ThemeOverlay.AppCompat.Dark`. But I'll keep digging. (And I have read that page. That was one of my starting points. Still doesn't seem to work.) – Liminal Oct 22 '14 at 09:35
  • 1
    Sorry about that. Left the background color of the Toolbar out for simplicity and haven't tested the results. I've revised the answer accordingly. I haven't found a way to do this only using styles though. As my app has different color schemes, I use `android:background="?attr/colorPrimary"` in the Toolbar and `@color/background_material_dark` in my style so it automatically adapts the primary app color. – oRRs Oct 22 '14 at 09:47
  • `popupTheme` is only available in Android L though... doesn't this break compatibility? – Kenny Worden Nov 18 '14 at 23:18
  • @Kenny make sure that you use `app:popupTheme` not `android:popupTheme`. The first one is from the `AppCompat` library so it's backwards compatible. – oRRs Nov 19 '14 at 07:13
  • I get ERROR "Element android.support.v7.widget.Toolbar doesnt have required attribute layout_height" ?? – Jemshit Jan 15 '15 at 08:52
  • OK, instead of " xmlns:android="http://schemas.android.com/apk/res-auto" i placed "xmlns:android="http://schemas.android.com/apk/res/android", worked :) – Jemshit Jan 15 '15 at 08:58
  • Hehe, Thanks so much guys, you are all great. Works well. The most time I had a strange result because I didn't overrode primary color with "android:colorPrimary" and just wrote colorPrimary (like in normal value-"0" folder... :P) – Martin Pfeffer Mar 05 '15 at 00:49
  • Thanks. I had followed the step in http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html under section "DarkActionBar" but it doesn't work. Your additional line makes it works : `android:background="@color/background_material_dark"` – Cheok Yan Cheng May 16 '15 at 19:58
  • 1
    this is not working anymore in app compat 23 and the title is black and not white :/ – Rashad.Z Oct 13 '15 at 11:31
  • @rashad.z I just tested this in a clean project and it worked as expected. You probably have styles changing the text colors. But as app:theme is deprecated now, I edited the answer with the new best practice so you may want to give it another try. – oRRs Oct 13 '15 at 15:22
  • Can you please s/DarkActionbar/DarkActionBar/ in Theme.AppCompat.Light.DarkActionbar? – philo Dec 01 '15 at 06:39
  • 23
    is there any way to get a grip on this jungle of themes and styles? – axd Feb 28 '16 at 10:30
  • 1
    I am using Android Studio 2.2. Project template with an Basic Activity gives a better example. – hotpro Oct 09 '16 at 23:25
  • 1
    One of the best answers in the whole web. One that makes some sense, at least. It is amazing how confusing this subject is. Actually, I think it's a role model for front-end development disgrace!!! Period. – dpant Jul 28 '19 at 10:21
71

Edit: After updating to appcompat-v7:22.1.1 and using AppCompatActivity instead of ActionBarActivity my styles.xml looks like:

<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
</style>

Note: This means I am using a Toolbar provided by the framework (NOT included in an XML file).

This worked for me:
styles.xml file:

<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="windowActionBar">false</item>
    <item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
</style>

Update: A quote from Gabriele Mariotti's blog.

With the new Toolbar you can apply a style and a theme. They are different! The style is local to the Toolbar view, for example the background color. The app:theme is instead global to all ui elements inflated in the Toolbar, for example the color of the title and icons.

LordRaydenMK
  • 13,074
  • 5
  • 50
  • 56
  • "Error: No resource found that matches the given name: attr 'colorPrimary'." We are talking about using appcompat_v7 here. – Yar Mar 19 '15 at 13:24
  • For me, this works only on Lollipop devices. On pre-lollipop not only the action bar, but all the activity use the dark theme, which is not what I wanted. I upvoted, but at the end I used the oRRs answer, styling the single Toolbar view. – lorenzo-s May 04 '15 at 09:20
  • @lorenzo-s I updated my answer for the latest version of appcompat. I also tested it on Galaxy Nexus with android 4.3 and it's working – LordRaydenMK May 04 '15 at 18:57
31

Ok after having sunk way to much time into this problem this is the way I managed to get the appearance I was hoping for. I'm making it a separate answer so I can get everything in one place.

It's a combination of factors.

Firstly, don't try to get the toolbars to play nice through just themes. It seems to be impossible.

So apply themes explicitly to your Toolbars like in oRRs answer

layout/toolbar.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:layout_alignParentTop="true"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:theme="@style/Dark.Overlay"
    app:popupTheme="@style/Dark.Overlay.LightPopup" />

However this is the magic sauce. In order to actually get the background colors I was hoping for you have to override the background attribute in your Toolbar themes

values/styles.xml:

<!-- 
    I expected android:colorBackground to be what I was looking for but
    it seems you have to override android:background
-->
<style name="Dark.Overlay" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="android:background">?attr/colorPrimary</item>
</style>

<style name="Dark.Overlay.LightPopup" parent="ThemeOverlay.AppCompat.Light">
    <item name="android:background">@color/material_grey_200</item>
</style>

then just include your toolbar layout in your other layouts

<include android:id="@+id/mytoolbar" layout="@layout/toolbar" />

and you're good to go.

Hope this helps someone else so you don't have to spend as much time on this as I have.

(if anyone can figure out how to make this work using just themes, ie not having to apply the themes explicitly in the layout files I'll gladly support their answer instead)

EDIT:

So apparently posting a more complete answer was a downvote magnet so I'll just accept the imcomplete answer above but leave this answer here in case someone actually needs it. Feel free to keep downvoting if it makes you happy though.

Community
  • 1
  • 1
Liminal
  • 1,709
  • 2
  • 12
  • 15
  • 2
    In my AppTheme I just put `@color/colorPrimary` Then I'm free to use `android:background="?attr/colorPrimary"` attribute in my Toolbar widget. – bytehala Feb 09 '15 at 07:56
  • May I know how do you get the definition of "@color/material_grey_200" ? – Cheok Yan Cheng May 16 '15 at 19:51
  • I don't remember exactly where but someone made a colors.xml file based on http://www.google.com/design/spec/style/color.html#color-color-palette can't find it now though – Liminal May 18 '15 at 07:38
  • 1
    @Liminal If you use `@android:color/transparent` you avoid the issue when you long press / click on a menu item there is a box around the text. This also future proofs it if the light background color changes in the future. – Ryan R Oct 16 '16 at 08:17
  • Doesn't work when you use CollapsingToolbarLayout though. – arekolek Oct 12 '17 at 11:24
  • I like this solution because you don't need an AppBarLayout. In my experience if you use AppBarLayout you need to set the theme in it instead of in Toolbar and for changing the background color you need to specify primaryColor inside the AppBarLayout's theme, if you don't use AppBarLayout primaryColor won't do anything in the Toolbar's theme, you need to set it with "android:background". – David Jan 15 '20 at 17:30
17

The cleanest way I found to do this is create a child of 'ThemeOverlay.AppCompat.Dark.ActionBar'. In the example, I set the Toolbar's background color to RED and text's color to BLUE.

<style name="MyToolbar" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="android:background">#FF0000</item>
    <item name="android:textColorPrimary">#0000FF</item>
</style>

You can then apply your theme to the toolbar:

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    app:theme="@style/MyToolbar"
    android:minHeight="?attr/actionBarSize"/>
Don
  • 659
  • 5
  • 6
13

To customize tool bar style, first create tool bar custom style inheriting Widget.AppCompat.Toolbar, override properties and then add it to custom app theme as shown below, see http://www.zoftino.com/android-toolbar-tutorial for more information tool bar and styles.

   <style name="MyAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="toolbarStyle">@style/MyToolBarStyle</item>
    </style>
    <style name="MyToolBarStyle" parent="Widget.AppCompat.Toolbar">
        <item name="android:background">#80deea</item>
        <item name="titleTextAppearance">@style/MyTitleTextAppearance</item>
        <item name="subtitleTextAppearance">@style/MySubTitleTextAppearance</item>
    </style>
    <style name="MyTitleTextAppearance" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
        <item name="android:textSize">35dp</item>
        <item name="android:textColor">#ff3d00</item>
    </style>
    <style name="MySubTitleTextAppearance" parent="TextAppearance.Widget.AppCompat.Toolbar.Subtitle">
        <item name="android:textSize">30dp</item>
        <item name="android:textColor">#1976d2</item>
    </style>
Arnav Rao
  • 6,692
  • 2
  • 34
  • 31
7

Yout can try this below.

<style name="MyToolbar" parent="Widget.AppCompat.Toolbar">
    <!-- your code here -->
</style>

And the detail elements you can find them in https://developer.android.com/reference/android/support/v7/appcompat/R.styleable.html#Toolbar

Here are some more:TextAppearance.Widget.AppCompat.Toolbar.Title, TextAppearance.Widget.AppCompat.Toolbar.Subtitle, Widget.AppCompat.Toolbar.Button.Navigation.

Hope this can help you.

Yong
  • 2,943
  • 1
  • 13
  • 11
  • 1
    Yup. With those I can get as far as getting the background color right and I finally figured out how to get the title-colors right. However the killer thing right now is that I can't figure out where the overflow button gets it's color. No matter what I change it stays so dark it doesn't show against my dark actionbar. If I change the theme to dark then it's light and shows up well.However no matter how much I dig around I can't figure out how to make the overflow icon show up light when I've started with a light theme – Liminal Oct 22 '14 at 09:17
0

Similar to Arnav Rao's, but with a different parent:

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    <item name="toolbarStyle">@style/MyToolbar</item>
</style>

<style name="MyToolbar" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="android:background">#ff0000</item>
</style>

With this approach, the appearance of the Toolbar is entirely defined in the app styles, so you don't need to place any styling on each toolbar.

craigmj
  • 4,827
  • 2
  • 18
  • 22
  • 2
    Actually `android:toolbarStyle` is API 21+ for `android.widget.Toolbar`. `toolbarStyle` is AppCompat for `android.support.v7.widget.Toolbar`. – Eugen Pechanec Oct 15 '17 at 19:12
  • I had thought Android Studio was giving me an issue with it, but on a second test, you're right! That's great news - I've been able to knock my minSDK down to 19 again, and it looks like my toolbarStyle is still working fine! Thank you! – craigmj Oct 15 '17 at 19:23
  • Just noticed! There's still the misunderstanding of *styles* vs. *themes*. `MyToolbar` style should extend `Widget.AppCompat.Toolbar` not a theme. – Eugen Pechanec Oct 15 '17 at 19:38