Comment puis-je styliser la barre d'outils appcompat-v7 comme Theme.AppCompat.Light.DarkActionBar?

105

J'essaie de recréer l'apparence de Theme.AppCompat.Light.DarkActionBaravec la nouvelle barre d'outils de la bibliothèque de support.

Si je choisis Theme.AppCompat.Lightma barre d'outils sera claire et si je choisis, Theme.AppCompatelle sera sombre. (Techniquement, vous devez utiliser la .NoActionBarversion, mais pour autant que je sache, la seule différence est

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

Maintenant il n'y a pas Theme.AppCompat.Light.DarkActionBarmais naïvement je pensais que ce serait assez bien de faire le mien

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

Cependant, avec cela, mes barres d'outils sont toujours Lightthématiques. J'ai passé des heures à essayer différentes combinaisons de mélange du thème Dark (de base) et du thème Light, mais je ne trouve tout simplement pas de combinaison qui me permette d'avoir des arrière-plans clairs sur tout sauf les barres d'outils.

Existe-t-il un moyen d'obtenir le AppCompat.Light.DarkActionBarlook avec les importations android.support.v7.widget.Toolbar?

Liminal
la source

Réponses:

216

La méthode recommandée pour styliser la barre d'outils pour un Light.DarkActionBarclone serait de l'utiliser Theme.AppCompat.Light.DarkActionbarcomme thème parent / d'application et d'ajouter les attributs suivants au style pour masquer la barre d'action par défaut:

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

Utilisez ensuite ce qui suit comme barre d'outils:

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

Pour d'autres modifications, vous créeriez des styles étendant ThemeOverlay.AppCompat.Dark.ActionBaret ThemeOverlay.AppCompat.Lightremplaçant ceux dans AppBarLayout->android:themeet Toolbar->app:popupTheme. Notez également que cela ramassera votre?attr/colorPrimary si vous l'avez défini dans votre style principal afin que vous puissiez obtenir une couleur d'arrière-plan différente.

Vous en trouverez un bon exemple dans le modèle de projet actuel avec Empty ActivityAndroid Studio (1.4+).

ORRs
la source
1
Eh bien oui tu peux. "Si vous souhaitez hériter des styles que vous avez définis vous-même, vous n'avez pas besoin d'utiliser l'attribut parent. Au lieu de cela, préfixez simplement le nom du style que vous souhaitez hériter au nom de votre nouveau style, séparé par un point . " developer.android.com/guide/topics/ui/themes.html#Inheritance
Liminal
1
En utilisant également le XML que vous avez posté, j'obtiens une barre d'outils blanche avec du texte blanc ou si je change le thème en ThemeOverlay.AppCompat.ActionBarj'obtiens une barre d'outils blanche avec du texte noir, donc cela ne semble pas fonctionner très bien. Ne semble pas comme les soins du système de l' <item name="android:colorBackground">@color/background_material_dark</item>en Base.ThemeOverlay.AppCompat.Dark. Mais je vais continuer à creuser. (Et j'ai lu cette page. C'était l'un de mes points de départ. Cela ne semble toujours pas fonctionner.)
Liminal
1
Désolé pour ça. A laissé la couleur d'arrière-plan de la barre d'outils pour plus de simplicité et n'a pas testé les résultats. J'ai révisé la réponse en conséquence. Cependant, je n'ai pas trouvé de moyen de le faire en utilisant uniquement des styles. Comme mon application a des combinaisons de couleurs différentes, j'utilise android:background="?attr/colorPrimary"dans la barre d'outils et <item name="colorPrimary">@color/background_material_dark</item>dans mon style afin qu'elle adapte automatiquement la couleur principale de l'application.
oRRs
1
cela ne fonctionne plus dans l'application compat 23 et le titre est noir et non blanc: /
Rashad.Z
21
existe-t-il un moyen de maîtriser cette jungle de thèmes et de styles?
axd
72

Edit: Après la mise à jour vers appcompat-v7: 22.1.1 et l'utilisation à la AppCompatActivityplace de ActionBarActivitymon styles.xml ressemble à:

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

Remarque: cela signifie que j'utilise un Toolbar fourni par le framework (NON inclus dans un fichier XML).

Cela a fonctionné pour moi:
fichier styles.xml:

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

Mise à jour: Une citation du blog de Gabriele Mariotti .

Avec la nouvelle barre d'outils, vous pouvez appliquer un style et un thème. Ils sont différents! Le style est local dans la vue de la barre d'outils, par exemple la couleur d'arrière-plan. Le thème app: est plutôt global à tous les éléments de l'interface utilisateur gonflés dans la barre d'outils, par exemple la couleur du titre et des icônes.

LordRaydenMK
la source
"Erreur: Aucune ressource trouvée correspondant au nom donné: attr 'colorPrimary'." Nous parlons ici d'utiliser appcompat_v7.
Yar
Pour moi, cela ne fonctionne que sur les appareils Lollipop. Sur pré-sucette non seulement la barre d'action, mais toute l'activité utilise le thème sombre, ce qui n'est pas ce que je voulais. J'ai voté pour, mais à la fin, j'ai utilisé la réponse oRRs, en stylisant la vue de la barre d'outils unique.
lorenzo-s
@ lorenzo-s J'ai mis à jour ma réponse pour la dernière version d'appcompat. Je l'ai également testé sur Galaxy Nexus avec Android 4.3 et cela fonctionne
LordRaydenMK
31

Ok, après avoir passé beaucoup de temps dans ce problème, c'est ainsi que j'ai réussi à obtenir l'apparence que j'espérais. J'en fais une réponse distincte pour que je puisse tout rassembler au même endroit.

C'est une combinaison de facteurs.

Tout d'abord, n'essayez pas de faire en sorte que les barres d'outils fonctionnent correctement à travers uniquement des thèmes. Cela semble impossible.

Appliquez donc les thèmes explicitement à vos barres d'outils comme dans la réponse oRRs

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

Cependant, c'est la sauce magique. Afin d'obtenir les couleurs d'arrière-plan que j'espérais, vous devez remplacer l' backgroundattribut dans les thèmes de votre barre d'outils

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>

puis incluez simplement votre disposition de barre d'outils dans vos autres mises en page

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

et vous êtes prêt à partir.

J'espère que cela aide quelqu'un d'autre pour que vous n'ayez pas à passer autant de temps que moi sur ce sujet.

(si quelqu'un peut comprendre comment faire ce travail en utilisant uniquement des thèmes, c'est-à-dire ne pas avoir à appliquer les thèmes explicitement dans les fichiers de mise en page, je soutiendrai volontiers leur réponse à la place)

ÉDITER:

Donc, apparemment, publier une réponse plus complète était un aimant pour un vote défavorable, je vais donc simplement accepter la réponse incomplète ci-dessus, mais laissez cette réponse ici au cas où quelqu'un en aurait réellement besoin. N'hésitez pas à continuer de voter si cela vous rend heureux.

Liminal
la source
2
Dans mon AppTheme, je viens de mettre <item name="colorPrimary">@color/colorPrimary</item> Ensuite, je suis libre d'utiliser l' android:background="?attr/colorPrimary"attribut dans mon widget Barre d'outils.
lemuel
Puis-je savoir comment obtenir la définition de "@ color / material_grey_200"?
Cheok Yan Cheng
Je ne me souviens pas exactement où mais quelqu'un a créé un fichier colors.xml basé sur google.com/design/spec/style/color.html#color-color-palette ne peut pas le trouver maintenant
Liminal
1
@Liminal Si vous utilisez, @android:color/transparentvous évitez le problème lorsque vous appuyez / cliquez longuement sur un élément de menu, il y a une boîte autour du texte. Cela le prouve également pour l'avenir si la couleur de fond clair change à l'avenir.
Ryan R
Cela ne fonctionne pas lorsque vous utilisez CollapsingToolbarLayout.
arekolek
17

Le moyen le plus propre que j'ai trouvé pour le faire est de créer un enfant de « ThemeOverlay.AppCompat.Dark.ActionBar ». Dans l'exemple, j'ai défini la couleur d'arrière-plan de la barre d'outils sur ROUGE et la couleur du texte sur BLEU.

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

Vous pouvez ensuite appliquer votre thème à la barre d'outils:

<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
la source
6
mon dieu c'était ça! textColorPrimary! Pourquoi était-ce si difficile à trouver n'importe où
Muppet
12

Pour personnaliser le style de la barre d'outils, créez d'abord un style personnalisé de la barre d'outils héritant de Widget.AppCompat.Toolbar, remplacez les propriétés, puis ajoutez-le au thème d'application personnalisé comme indiqué ci-dessous, voir http://www.zoftino.com/android-toolbar-tutorial pour plus d'informations sur la barre d'outils et les 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
la source
7

Vous pouvez essayer ceci ci-dessous.

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

Et les éléments de détail, vous pouvez les trouver dans https://developer.android.com/reference/android/support/v7/appcompat/R.styleable.html#Toolbar

Voici encore plus: TextAppearance.Widget.AppCompat.Toolbar.Title, TextAppearance.Widget.AppCompat.Toolbar.Subtitle, Widget.AppCompat.Toolbar.Button.Navigation.

J'espère que cela peut vous aider.

Yong
la source
1
Ouaip. Avec ceux-ci, je peux aller jusqu'à obtenir la bonne couleur d'arrière-plan et j'ai finalement compris comment obtenir les bonnes couleurs de titre. Cependant, le truc qui tue en ce moment, c'est que je ne peux pas savoir où le bouton de débordement obtient sa couleur. Peu importe ce que je change, il reste si sombre qu'il ne s'affiche pas sur ma barre d'action sombre. Si je change le thème en sombre, alors il est clair et apparaît bien.Cependant, peu importe combien je creuse, je ne peux pas comprendre comment faire apparaître l'icône de débordement lorsque j'ai commencé avec un thème clair
Liminal
0

Similaire à Arnav Rao, mais avec un parent différent:

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

Avec cette approche, l'apparence de la barre d'outils est entièrement définie dans les styles de l'application, vous n'avez donc pas besoin de placer de style sur chaque barre d'outils.

craigmj
la source
2
En fait, android:toolbarStylec'est l'API 21+ pour android.widget.Toolbar. toolbarStyleest AppCompat pour android.support.v7.widget.Toolbar.
Eugen Pechanec
J'avais pensé qu'Android Studio me posait un problème, mais lors d'un deuxième test, vous avez raison! C'est une excellente nouvelle - j'ai pu ramener mon minSDK à 19 à nouveau, et il semble que mon toolbarStyle fonctionne toujours bien! Je vous remercie!
craigmj
Juste remarqué! Il y a toujours un malentendu entre les styles et les thèmes . MyToolbarle style ne doit Widget.AppCompat.Toolbarpas étendre un thème.
Eugen Pechanec