How do I style appcompat-v7 Toolbar like Theme.AppCompat.Light.DarkActionBar?
Asked Answered
O

7

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?

Ordinary answered 22/10, 2014 at 8:25 Comment(0)
B
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+).

Bellinzona answered 22/10, 2014 at 9:15 Comment(16)
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." developer.android.com/guide/topics/ui/themes.html#InheritanceOrdinary
Thanks, didn't know that. Still, the rest of my answer should solve your question.Bellinzona
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 <item name="android:colorBackground">@color/background_material_dark</item> 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.)Ordinary
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 <item name="colorPrimary">@color/background_material_dark</item> in my style so it automatically adapts the primary app color.Bellinzona
popupTheme is only available in Android L though... doesn't this break compatibility?Typesetter
@Kenny make sure that you use app:popupTheme not android:popupTheme. The first one is from the AppCompat library so it's backwards compatible.Bellinzona
I get ERROR "Element android.support.v7.widget.Toolbar doesnt have required attribute layout_height" ??Prissie
OK, instead of " xmlns:android="schemas.android.com/apk/res-auto" i placed "xmlns:android="schemas.android.com/apk/res/android", worked :)Prissie
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)Shikoku
Thanks. I had followed the step in android-developers.blogspot.com/2014/10/… under section "DarkActionBar" but it doesn't work. Your additional line makes it works : android:background="@color/background_material_dark"Fluellen
this is not working anymore in app compat 23 and the title is black and not white :/Khedive
@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.Bellinzona
Can you please s/DarkActionbar/DarkActionBar/ in Theme.AppCompat.Light.DarkActionbar?Spangle
is there any way to get a grip on this jungle of themes and styles?Bander
I am using Android Studio 2.2. Project template with an Basic Activity gives a better example.Lordsandladies
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.Methylal
N
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.

Natural answered 28/10, 2014 at 19:4 Comment(3)
"Error: No resource found that matches the given name: attr 'colorPrimary'." We are talking about using appcompat_v7 here.Kenti
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.Apricot
@Apricot I updated my answer for the latest version of appcompat. I also tested it on Galaxy Nexus with android 4.3 and it's workingNatural
O
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.

Ordinary answered 22/10, 2014 at 11:1 Comment(6)
In my AppTheme I just put <item name="colorPrimary">@color/colorPrimary</item> Then I'm free to use android:background="?attr/colorPrimary" attribute in my Toolbar widget.Marybelle
May I know how do you get the definition of "@color/material_grey_200" ?Fluellen
I don't remember exactly where but someone made a colors.xml file based on google.com/design/spec/style/color.html#color-color-palette can't find it now thoughOrdinary
@Ordinary 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.Henna
Doesn't work when you use CollapsingToolbarLayout though.Wafd
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".Molliemollify
S
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"/>
Snoopy answered 13/11, 2014 at 18:42 Comment(1)
my god this was it! textColorPrimary! Why was this so goddamn hard to find anywhereStefanysteffane
P
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>
Photofluorography answered 19/10, 2017 at 4:17 Comment(0)
S
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.

Serialize answered 22/10, 2014 at 8:35 Comment(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 themeOrdinary
F
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.

Frere answered 15/10, 2017 at 19:7 Comment(3)
Actually android:toolbarStyle is API 21+ for android.widget.Toolbar. toolbarStyle is AppCompat for android.support.v7.widget.Toolbar.Ear
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!Frere
Just noticed! There's still the misunderstanding of styles vs. themes. MyToolbar style should extend Widget.AppCompat.Toolbar not a theme.Ear

© 2022 - 2024 — McMap. All rights reserved.