Boutons de coloration dans Android avec Material Design et AppCompat

256

Avant la AppCompatsortie de la mise à jour aujourd'hui, j'ai pu changer la couleur des boutons dans Android L mais pas sur les anciennes versions. Après avoir inclus la nouvelle mise à jour AppCompat, je ne peux pas changer la couleur de l'une ou l'autre version, lorsque j'essaie, le bouton disparaît. Quelqu'un sait-il comment changer la couleur du bouton?

Les images suivantes montrent ce que je veux réaliser:

image montrant le résultat souhaité

Le bouton blanc est par défaut, le rouge est ce que je veux.

C'est ce que je faisais précédemment pour changer la couleur des boutons dans styles.xml:

<item name="android:colorButtonNormal">insert color here</item>

et pour le faire dynamiquement:

button.getBackground().setColorFilter(getResources().getColor(insert color here), PorterDuff.Mode.MULTIPLY);

Aussi je l'ai fait changer le parent thème de @android:style/Theme.Material.Light.DarkActionBarlaTheme.AppCompat.Light.DarkActionBar

mail929
la source
J'ai essayé la même chose mais rien n'a changé la couleur du bouton. J'ai également supprimé Android: de l'attribut car il provient de la bibliothèque de support et ne fait pas partie de l'espace de noms Android
Informatic0re
Si vous utilisez Android: colorButtonNormal avec Android 5.0, cela fonctionne - mais il ne semble pas être rétrocompatible
Informatic0re
Oui, c'est exactement ce que je
vivais
J'ai également compris que la couleur d'accent ne change pas la couleur de la CheckBox, mais c'est le cas dans les anciennes versions
Informatic0re
plus un pour cette méthode dynamique. :)
theapache64

Réponses:

222

Corrigé officiellement dans la bibliothèque de support rev.22 (ven 13 mars 2015). Voir le problème de code Google pertinent:

https://issuetracker.google.com/issues/37008632

Exemple d'utilisation

theme.xml:

<item name="colorButtonNormal">@color/button_color</item>

v21 / theme.xml

<item name="android:colorButtonNormal">@color/button_color</item>
Coureur du vent
la source
17
Y a-t-il un exemple comment l'utiliser? Comment puis-je définir des couleurs sur un seul bouton?
Intrications
3
@WindRider J'ai un problème cependant, je veux l'utiliser pour créer des boutons de différentes couleurs. Je crée des styles Button.Red, Button.Green, tous avec un parent égal au style de base Button. J'ai défini l'élément colorButtonNormal sur la couleur demandée, définissez-le comme thème de bouton. Malheureusement, il ne colore que les boutons pour 21. En dessous, il ne remplace pas colorButtonNormal défini dans le thème.
dominik4142
71
Avec AppCompat 22.1.1, cela fonctionne pour moi sur 2.3.7, 4.4.4 et 5.1 aussi pour un seul bouton: définir les boutons android:theme="@style/ColoredButton"et dans styles.xml <style name="ColoredButton" parent="Widget.AppCompat.Button"> <item name="colorButtonNormal">@color/button_yellow</item> </style>
hunyadym
2
@hunyadym, l'ajout d'un thème aux boutons s'arrête surClick pour une raison quelconque. Je classerais cela comme une solution de contournement jusqu'à ce que la bibliothèque de conception fournisse un meilleur moyen.
ravi le
3
@gladed: Il semble que dans votre cas, le problème soit ce bug: code.google.com/p/android/issues/detail?id=62795#c1
hunyadym
148

Modifier (22.06.2016):

La bibliothèque Appcompat a commencé à prendre en charge les boutons de matériau après avoir publié la réponse d'origine. Dans cet article vous pouvez voir la mise en œuvre la plus simple des boutons surélevés et plats.

Réponse originale:

Étant donné que AppCompat ne prend pas encore en charge le bouton, vous pouvez utiliser xml comme arrière-plan. Pour ce faire, j'ai regardé le code source d'Android et trouvé les fichiers associés pour styliser les boutons de matériau.

1 - Regardez l'implémentation originale du bouton matériel depuis la source.

Jetez un oeil à la btn_default_material.xml sur le code source Android .

Vous pouvez copier le fichier dans le dossier drawable-v21 de votre projet. Mais ne touchez pas à la couleur ici. Le fichier que vous devez modifier est le deuxième fichier.

drawable-v21 / custom_btn.xml

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?attr/colorControlHighlight">
    <item android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>

2 - Obtenez la forme du bouton du matériau d'origine

Comme vous vous en rendez compte, il y a une forme utilisée à l'intérieur de ce dessin que vous pouvez trouver dans ce fichier du code source .

<inset xmlns:android="http://schemas.android.com/apk/res/android"
   android:insetLeft="@dimen/button_inset_horizontal_material"
   android:insetTop="@dimen/button_inset_vertical_material"
   android:insetRight="@dimen/button_inset_horizontal_material"
   android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
    <corners android:radius="@dimen/control_corner_material" />
    <solid android:color="?attr/colorButtonNormal" />
    <padding android:left="@dimen/button_padding_horizontal_material"
             android:top="@dimen/button_padding_vertical_material"
             android:right="@dimen/button_padding_horizontal_material"
             android:bottom="@dimen/button_padding_vertical_material" />
</shape>

3 - Obtenir les dimensions du bouton matériel

Et dans ce fichier, vous trouverez quelques dimensions utilisées dans le fichier que vous pouvez trouver ici . Vous pouvez copier le fichier entier et le placer dans votre dossier de valeurs . Ceci est important pour appliquer la même taille (utilisée dans les boutons de matériau) à tous les boutons

4 - Créez un autre fichier dessinable pour les anciennes versions

Pour les anciennes versions, vous devriez avoir un autre dessinable avec le même nom. Je mets directement les éléments en ligne au lieu de les référencer. Vous voudrez peut-être les référencer. Mais encore une fois, la chose la plus importante est les dimensions d'origine du bouton matériel.

drawable / custom_btn.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!-- pressed state -->
    <item android:state_pressed="true">
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/PRESSED_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
    
    <!-- focused state -->
    <item android:state_focused="true">
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/FOCUSED_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
    
    <!-- normal state -->
    <item>
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/NORMAL_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
</selector>

Résultat

Votre bouton aura un effet d'entraînement sur les appareils Lollipop. Les anciennes versions auront exactement le même bouton sauf l'effet d'entraînement. Mais puisque vous fournissez des éléments de dessin pour différents états, ils répondront également aux événements tactiles (comme à l'ancienne).

eluleci
la source
4
Oui, exactement. Si vous utilisez le même arrière-plan pour tous les boutons et si vous ne voulez pas l'ajouter encore et encore, définissez un style de bouton dans votre styles.xml <style name = "ButtonStyle" parent = "android: Widget.Button"> < item name = "android: background"> ​​@ drawable / custom_btn </item> </style> et ajoutez un style de bouton dans votre thème <item name = "android: buttonStyle"> @ style / ButtonStyle </item>
eluleci
1
comment puis-je ajouter une élévation à ce bouton sur pré-21? si je comprends bien, je devrais ajouter une nouvelle forme avec une ombre sous le bouton, mais où dois-je exactement le mettre?
xakz
7
Très ennuyeux que cela ne soit pas pris en charge hors de la boîte
Sam
39
Je suis totalement d'accord avec vous. Le bouton est le widget le plus utilisé mais il n'est pas inclus dans la bibliothèque de support pour le matériel. Je me demande à quoi ils pensaient.
eluleci
1
De plus, en suivant votre guide, il semble que l'arrière-plan ne s'affiche pas du tout ...
JMRboosties
111

Cela a été amélioré dans la version 23.0.0 de la bibliothèque AppCompat avec l'ajout de plus de thèmes, y compris

Widget.AppCompat.Button.Colored

Tout d'abord, incluez la dépendance appCompat si vous ne l'avez pas déjà fait

compile('com.android.support:appcompat-v7:23.0.0') {
    exclude group: 'com.google.android', module: 'support-v4'
}

Maintenant, puisque vous devez utiliser la version 23 de l'application compatible, vous devrez également cibler le SDK-v23!

    compileSdkVersion = 23
    targetSdkVersion = 23

Dans votre values/theme

<item name="android:buttonStyle">@style/BrandButtonStyle</item>

Dans votre values/style

<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="colorButtonNormal">@color/yourButtonColor</item>
    <item name="android:textColor">@color/White</item>
</style>

Dans votre values-v21/style

<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="android:colorButtonNormal">@color/yourButtonColor</item>
    <item name="android:textColor">@color/White</item>
</style>

Puisque le thème de votre bouton est basé sur Widget.AppCompat.Button.ColoredLa couleur du texte sur le bouton est par défaut le blanc!

mais il semble qu'il y ait un problème lorsque vous désactivez le bouton, le bouton changera sa couleur en gris clair, mais la couleur du texte restera blanche!

une solution consiste à définir spécifiquement la couleur du texte du bouton sur blanc! comme je l'ai fait dans le style montré ci-dessus.

maintenant, vous pouvez simplement définir votre bouton et laisser AppCompat faire le reste :)

<Button
        android:layout_width="200dp"
        android:layout_height="48dp" />

État désactivé État désactivé

État activé État activé

Éditer:

Ajouter <Button android:theme="@style/BrandButtonStyle"/>

Muhammad Alfaifi
la source
19
C'est la meilleure façon de le faire, maintenant! Vous pouvez également utiliser le style sur des boutons individuels avec <Button android:theme="@style/BrandButtonStyle"/>. Ce doit être l' themeattribut et non l' styleattribut.
mohlendo
7
@Muhammad Alfaifi Avez-vous un exemple de projet ou un résumé pour cela? J'ai créé un projet propre et cela ne fonctionne pas: github.com/Bresiu/ThemeTest . Dans les couleurs de bouton Lolipop avec couleur d'accentuation et sur API v16, le bouton reste gris: i.imgur.com/EVwkpk2.png
Bresiu
4
Cela ne m'a fonctionné que lors de la spécification de l'attribut android: theme. Je n'ai pas pu faire fonctionner le style d'attribut avec la balise button.
Ray Hunter
8
En utilisant la lib v23.1, cela ne fonctionnait pas correctement, il montrait toujours la couleur d'accent comme bg, pas celle définie, quand on essayait de la régler sur le thème entier
Patrick Favre
3
Même problème ici, sur v23.1 le bouton désactivé est de la même couleur que le bouton activé. Très frustrant. quelqu'un le comprend?
AhmedW
63

Dans la bibliothèque de support Android 22.1.0, Google a rendu la Buttonteinte sensible. Donc, une autre façon de personnaliser la couleur d'arrière-plan du bouton est d'utiliser lebackgroundTint attribut.

Par exemple,

<Button
       android:id="@+id/add_remove_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:backgroundTint="@color/bg_remove_btn_default"
       android:textColor="@android:color/white"
       tools:text="Remove" />
Manabu-GT
la source
1
Finalement! Article de
GuillermoMP
5
La documentation indique: "Cela sera automatiquement utilisé lorsque vous utiliserez Button dans vos présentations. Vous ne devez utiliser manuellement cette classe que lors de l'écriture de vues personnalisées." developer.android.com/reference/android/support/v7/widget/… cela signifie-t-il que nous n'avons pas à modifier manuellement toutes nos mises en page et notre code java?
Stephane
@Stephane non, nous devons changer les dispositions. chris.banes.me/2015/04/22/support-libraries-v22-1-0
Anton Holovin
IMPRESSIONNANT! Maintenant, existe-t-il un AppCompatToggleButton qui vous permet de modifier l'arrière-plan des ToggleButtons? Peut-être que je peux plagier le code ...
swooby
19
Malheureusement, cela ne fonctionne que sur l'API 21+. L'attribut android: backgroundTint ne fonctionne pas sur pré-Lollipop même avec la bibliothèque AppCompat. Seul colorButtonNormal du thème fonctionne sur pré-Lollipop.
Timur_C
42

Pour prendre en charge les boutons de couleur, utilisez la dernière bibliothèque AppCompat (> 23.2.1 ) avec:

gonfler - XML

Widget AppCompat:

android.support.v7.widget.AppCompatButton

Style AppCompat:

style="@style/Widget.AppCompat.Button.Colored"

NB! Pour définir une couleur personnalisée en xml: utilisez l'attr: appau lieu deandroid

(utiliser alt+enterou déclarer xmlns:app="http://schemas.android.com/apk/res-auto"utiliser app)

app : backgroundTint = "@ color / your_custom_color"

Exemple:

<android.support.v7.widget.AppCompatButton
     style="@style/Widget.AppCompat.Button.Colored"
     app:backgroundTint="@color/your_custom_color"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"     
     android:text="Colored Button"/>

ou définissez-le par programme - JAVA

 ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));
TouchBoarder
la source
Votre code Java a fonctionné pour moi. Et la réponse de Muhammad Alfaifi a aidé à définir la couleur du texte du bouton.
Micro
existe-t-il un moyen facile de définir la teinte par programme (pas en arrière-plan)?
saut
Merveilleux! Fonctionne également sur 4.4.4! Et l'état du sélecteur est également très bien maintenu!
sud007
Selon les documents : Ceci est automatiquement utilisé lors de la définition des boutons dans vos mises en page. Vous devez uniquement spécifier AppCompatButton lors de la création de vues personnalisées.
gMale
Fait intéressant, les modifications XML ont parfaitement fonctionné dans un fragment, mais pas dans une présentation d'activité. Les boutons d'activité utilisaient uniquement colorAccent. La version programmatique a fonctionné cependant.
Leon
25

Avec la dernière bibliothèque de support, vous pouvez simplement hériter de votre activité AppCompatActivity, de sorte qu'elle gonflera votre Buttonas AppCompatButtonet vous donnera la possibilité de styliser la couleur de chaque bouton de la mise en page à l'aide de android:theme="@style/SomeButtonStyle", où SomeButtonStyleest:

<style name="SomeButtonStyle" parent="@android:style/Widget.Button">
    <item name="colorButtonNormal">@color/example_color</item>
</style>

A travaillé pour moi en 2.3.7, 4.4.1, 5.0.2

Artem
la source
Merci!!! Je viens de changer la valeur parent pour "Widget.AppCompat.EditText" car j'ai besoin de mettre à jour le style EditText.
Juan Saravia
3
Merci, ça a aussi fonctionné pour moi. Assurez-vous d'utiliser android:themeet non style. Vous pouvez également ajouter colorControlHighlightet colorControlActivated.
Rachel
ne fonctionne pas, API 22, AppCompatActivity, thème Material.Light
Andrey Uglev
1
@AndreyUglev essaie d'utiliser à la Theme.AppCompat.Lightplace.
Artem
Salut, cela change la couleur désirée MAIS supprime les ombres.
Amio.io
16

si vous voulez ci-dessous le style

entrez la description de l'image ici

ajoutez ce style à votre bouton

style="@style/Widget.AppCompat.Button.Borderless.Colored"

si vous voulez ce style

entrez la description de l'image ici

ajouter le code ci-dessous

style="@style/Widget.AppCompat.Button.Colored"
Jinu
la source
1
compile 'com.android.support:appcompat-v7:23.1.0'Vous devez avoir à ajouter.
Pratik Butani
1
mais la question est de savoir comment avoir des boutons matériels avec des couleurs différentes, afin que tous n'aient pas la couleur principale du thème.
Apostrofix
15

La réponse est dans THEME pas style

Le problème est que la couleur du bouton colle au colorButtonNormal du thème. J'ai essayé de changer le style de différentes manières sans succès. J'ai donc changé le thème du bouton .

Créez un thème avec colorButtonNormal et colorPrimary:

<style name="ThemeAwesomeButtonColor" parent="AppTheme">
    <item name="colorPrimary">@color/awesomePrimaryColor</item>
    <item name="colorButtonNormal">@color/awesomeButtonColor</item>
</style>

Utilisez ce thème dans le bouton

<Button
        android:id="@+id/btn_awesome"
        style="@style/AppTheme.Button"
        android:theme="@style/ThemeAwesomeButtonColor"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_awesome"/>

Le "AppTheme.Button" peut être n'importe quelle chose qui étend le style de bouton comme ici j'utilise la couleur primaire pour la couleur du texte:

<style name="AppTheme.Button" parent="Base.Widget.AppCompat.Button">
    ...
    <item name="android:textColor">?attr/colorPrimary</item>
    ...
</style>

Et vous obtenez le bouton dans n'importe quelle couleur que vous souhaitez compatible avec la conception des matériaux.

lonelyboycs
la source
quels sont les autres attributs que je peux ajouter dans les styles.
Sagar Nayak
4

Je viens de créer une bibliothèque Android, qui vous permet de modifier facilement la couleur du bouton et la couleur de l'ondulation

https://github.com/xgc1986/RippleButton

<com.xgc1986.ripplebutton.widget.RippleButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn"
    android:text="Android button modified in layout"
    android:textColor="@android:color/white"
    app:buttonColor="@android:color/black"
    app:rippleColor="@android:color/white"/>

Vous n'avez pas besoin de créer un style pour chaque bouton que vous souhaitez avec une couleur différente, vous permettant de personnaliser les couleurs au hasard

xgc1986
la source
4

ce travail pour moi avec appcompat-v7: 22.2.0 dans android + 4.0

dans vos styles.xml

<style name="Button.Tinted" parent="Widget.AppCompat.Button">
    <item name="colorButtonNormal">YOUR_TINT_COLOR</item>
    <item name="colorControlHighlight">@color/colorAccent</item>
    <item name="android:textColor">@android:color/white</item>
</style>

dans votre fichier de mise en page

<Button
    android:id="@+id/but_next"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/but_continue"
    android:theme="@style/Button.Tinted" />
ingyesid
la source
Salut, cela change la couleur désirée MAIS supprime les ombres.
Amio.io
Salut encore, je peux voir. C'est un bon comportement maintenant.
Amio.io
Comment pouvez-vous faire cela en Java?
Micro
@MicroR vérifiez la réponse ci-dessus.
ingyesid
4

Disposition:

<android.support.v7.widget.AppCompatButton
  style="@style/MyButton"
  ...
  />

styles.xml:

<style name="MyButton" parent="Widget.AppCompat.Button.Colored">
  <item name="backgroundTint">@color/button_background_selector</item>
  <item name="android:textColor">@color/button_text_selector</item>
</style>

color / button_background_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="#555555"/>
    <item android:color="#00ff00"/>
</selector>

color / button_text_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="#888888"/>
    <item android:color="#ffffff"/>
</selector>
BArtWell
la source
3

Pour ceux qui utilisent un ImageButtonici, voici comment procéder:

Dans style.xml:

<style name="BlueImageButton" parent="Base.Widget.AppCompat.ImageButton">
    <item name="colorButtonNormal">@color/primary</item>
    <item name="android:tint">@color/white</item>
</style>

dans v21 / style.xml:

<style name="BlueImageButton" parent="Widget.AppCompat.ImageButton">
    <item name="android:colorButtonNormal">@color/primary</item>
    <item name="android:tint">@color/white</item>
</style>

Puis dans votre fichier de mise en page:

<android.support.v7.widget.AppCompatImageButton
    android:id="@+id/my_button"
    android:theme="@style/BlueImageButton"
    android:layout_width="42dp"
    android:layout_height="42dp"
    android:layout_gravity="center_vertical"
    android:src="@drawable/ic_check_black_24dp"
    />
Micro
la source
Cela a aidé .... Je suppose qu'il est important de noter d'appliquer le style de bouton en tant que thème au lieu d'un style dans le widget Button. Je l'appliquais sous style = "@ style / BlueImageButton" et cela n'a pas fonctionné
velval
3

Si vous utilisez une solution de style avec colorButtonNormal , n'oubliez pas d'hériter de Widget.AppCompat.Button.Colored pour que l'effet d'entraînement fonctionne;)

Comme

<style name="CustomButtonStyle" parent="Widget.AppCompat.Button.Colored">
      <item name="colorButtonNormal">@android:color/white</item>
</style>
didi.yeah
la source
2

Une autre solution simple utilisant AppCompatButton

<android.support.v7.widget.AppCompatButton
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     style="@style/Widget.AppCompat.Button.Colored"
     app:backgroundTint="@color/red"
     android:text="UNINSTALL" />
Hanzyusuf
la source
2

Utilisation:

android:backgroundTint="@color/customColor"

Ou même :

android:background="@color/customColor"

et cela donnera une couleur personnalisée au bouton.

SuKu
la source
1

Si vous souhaitez uniquement un bouton de matériau "Plat", vous pouvez personnaliser leur arrière-plan à l'aide de l' attribut selectableItemBackground, comme expliqué ici .

kiruwka
la source
Si vous ne voulez changer aucune des couleurs de «teinte» ou des couleurs sélectionnées, c'est certainement une solution facile pour obtenir toujours un retour avec des boutons colorés. Merci!
theblang
1

Pour changer la couleur d'un seul bouton

ViewCompat.setBackgroundTintList(button, getResources().getColorStateList(R.color.colorId));
Jaydeep Solanki
la source
1

Pour moi, le problème était que dans Android 5.0, cela android:colorButtonNormaln'avait aucun effet, et en fait, aucun élément du thème (comme android:colorAccent), mais dans Android 4.4.3, par exemple. Le projet a été configuré avec compileSdkVersionet targetSdkVersionà 22, j'ai donc apporté toutes les modifications au fur et à mesure que @Muhammad Alfaifi a suggéré, mais à la fin, j'ai remarqué que le problème était le buildToolsVersion , qui n'a pas été mis à jour. Une fois que je suis passé à 23.0.1 , tout commence à fonctionner presque normalement. Maintenant, le android:colorButtonNormaln'a toujours aucun effet, mais au moins le bouton réagit àandroid:colorAccent , ce qui pour moi est acceptable.

J'espère que cet indice pourrait aider quelqu'un. Remarque: J'ai appliqué le style directement au bouton, car le bouton android:theme=[...]n'a pas non plus d'effet.

Bianca Daniciuc
la source
Vous avez presque trouvé la manière 100% correcte d'utiliser le nouveau @ style / Widget.AppCompat.Button.Colored;) - voir cette réponse stackoverflow.com/a/35811157/19733911
sosite
1

Une façon de retirer cela vous permet de simplement pointer vers un style et de NE PAS thématiser TOUS les boutons de votre application de la même manière.
Dans themes.xml, ajoutez un thème

    <style name="Theme.MyApp.Button.Primary.Blue" parent="Widget.AppCompat.Button">
        <item name="colorButtonNormal">@color/someColor</item>
        <item name="android:textColorPrimary">@android:color/white</item>
    </style>

Maintenant, dans styles.xml, ajoutez

    <style name="MyApp.Button.Primary.Blue" parent="">
        <item name="android:theme">@style/Theme.MyApp.Button.Primary.Blue</item>
    </style>

Maintenant, dans votre mise en page, pointez simplement le STYLE dans votre bouton

    <Button
        ...
        style="@style/MyApp.Button.Primary.Blue"
        ...  />
Douglas 'DK' Knudsen
la source
1

METTRE À JOUR

Utilisez la bibliothèque de support de conception (23.2.0) et les widgets compatibles avec les applications comme ci-dessous

Dans la bibliothèque de support Android 22.1 :

Cela se fait automatiquement lors du gonflage des mises en page - en remplaçant Button par AppCompatButton, TextView par AppCompatTextView, etc. pour garantir que chacun puisse prendre en charge la teinture. Dans cette version, ces widgets sensibles à la teinte sont désormais accessibles au public, vous permettant de conserver la prise en charge de la teinture même si vous devez sous-classer l'un des widgets pris en charge.

La liste complète des widgets sensibles aux teintes:

AppCompatAutoCompleteTextView
AppCompatButton
AppCompatCheckBox
AppCompatCheckedTextView
AppCompatEditText
AppCompatMultiAutoCompleteTextView
AppCompatRadioButton
AppCompatRatingBar
AppCompatSpinner
AppCompatTextView

Conception matérielle pour les dispositifs pré-sucettes :

AppCompat (alias ActionBarCompat) a commencé comme un backport de l'API ActionBar d'Android 4.0 pour les appareils fonctionnant sur Gingerbread, fournissant une couche d'API commune au-dessus de l'implémentation rétroportée et de l'implémentation du framework. AppCompat v21 fournit une API et un ensemble de fonctionnalités à jour avec Android 5.0


Amit Vaghela
la source
1

Si vous souhaitez utiliser le style AppCompat comme Widget.AppCompat.Button , Base.Widget.AppCompat.Button.Colored , etc., vous devez utiliser ces styles avec des vues compatibles de la bibliothèque de support.

Le code ci-dessous ne fonctionne pas pour les appareils pré-lolipop:

<Button
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:theme="@style/Widget.AppCompat.Button" />

Vous devez utiliser AppCompatButton pour activer les styles AppCompat:

<android.support.v7.widget.AppCompatButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:theme="@style/Widget.AppCompat.Button" />
farukcankaya
la source
2
Les widgets de compatibilité d'application ne sont-ils pas utilisés automatiquement lors du gonflement des dispositions XML? Je crois qu'il ImageViewest remplacé par AppCompatImageViewet cela devrait être le même avec tous les widgets, qui ont la AppCompatversion correspondante .
d.aemon
Non, si vous ne ciblez pas la dernière version cible, vous devez définir android.support.v7.widget.AppCompatImageViewexplicitement.
farukcankaya
Que voulez-vous dire par last target version@power?
d.aemon
1

J'utilise ça. L'effet d'entraînement et le bouton cliquent sur le travail de l'ombre.

style.xml

<style name="Button.Red" parent="Widget.AppCompat.Button.Colored">
    <item name="android:textColor">@color/material_white</item>
    <item name="android:backgroundTint">@color/red</item>
</style>

Bouton sur la mise en page:

<Button
        style="@style/Button.Red"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/close"/>
Infliger
la source
0

En fait, je ne voulais pas changer mes styles de boutons personnalisés, mais malheureusement, ils ne fonctionnaient plus.

Mon application a une version minSdk de 9 et tout fonctionnait auparavant.

Je ne sais pas pourquoi mais depuis que j'ai supprimé l'androïde: avant le buttonStyle il semble fonctionner à nouveau

maintenant = travail:

<item name="buttonStyle">@style/ButtonmyTime</item>

avant = juste des boutons de matière grise:

<item name="android:buttonStyle">@style/ButtonmyTime</item>

Je n'ai pas de dossier spécial pour la nouvelle version Android car mes boutons sont assez plats et ils devraient être identiques sur toutes les versions Android.

Peut-être que quelqu'un peut me dire pourquoi j'ai dû supprimer le "android:" Le ImageButton fonctionne toujours avec "android:"

<item name="android:imageButtonStyle">@style/ImageButtonmyTimeGreen</item>
Stefan
la source
0

Après 2 jours à chercher des réponses, le thème des boutons ne fonctionnait pas pour moi dans l'API <21.

Ma seule solution est de remplacer la teinture AppCompatButton non seulement avec le thème de l'application de base "colorButtonNormal", mais aussi avec la vue backgroundTint comme ceci:

public class AppCompatColorButton extends AppCompatButton {

    public AppCompatColorButton(Context context) {
        this(context, null);
    }

    public AppCompatColorButton(Context context, AttributeSet attrs) {
        this(context, attrs, android.support.v7.appcompat.R.attr.buttonStyle);
    }

    public AppCompatColorButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        if (TintManager.SHOULD_BE_USED) {
            setSupportBackgroundTintList(createButtonColorStateList(getContext(), attrs, defStyleAttr));
        }
    }

    static final int[] DISABLED_STATE_SET = new int[]{-android.R.attr.state_enabled};
    static final int[] FOCUSED_STATE_SET = new int[]{android.R.attr.state_focused};
    static final int[] PRESSED_STATE_SET = new int[]{android.R.attr.state_pressed};
    static final int[] EMPTY_STATE_SET = new int[0];

    private ColorStateList createButtonColorStateList(Context context, AttributeSet attrs, int defStyleAttr) {
        final int[][] states = new int[4][];
        final int[] colors = new int[4];
        int i = 0;

        final int themeColorButtonNormal = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
        /*TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.backgroundTint }, defStyleAttr, 0);
        final int colorButtonNormal = a.getColor(0, themeColorButtonNormal);*/
        TypedArray a = context.obtainStyledAttributes(attrs, android.support.v7.appcompat.R.styleable.View, defStyleAttr, 0);
        final int colorButtonNormal = a.getColor(android.support.v7.appcompat.R.styleable.View_backgroundTint, themeColorButtonNormal);
        a.recycle();
        final int colorControlHighlight = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorControlHighlight);

        // Disabled state
        states[i] = DISABLED_STATE_SET;
        colors[i] = ThemeUtils.getDisabledThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
        i++;

        states[i] = PRESSED_STATE_SET;
        colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
        i++;

        states[i] = FOCUSED_STATE_SET;
        colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
        i++;

        // Default enabled state
        states[i] = EMPTY_STATE_SET;
        colors[i] = colorButtonNormal;
        i++;

        return new ColorStateList(states, colors);
    }
}

Vous pouvez ensuite définir la couleur de votre bouton comme ceci:

<com.example.views.AppCompatColorButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:backgroundTint="#ffff0000"
            app:backgroundTint="#ffff0000"
            android:text="Button"
            android:textColor="@android:color/white" />
Thomas G.
la source
0

Cette réponse SO m'a aidé à arriver à une réponse https://stackoverflow.com/a/30277424/3075340

J'utilise cette méthode utilitaire pour définir la teinte d'arrière-plan d'un bouton. Il fonctionne avec des appareils pré-sucettes:

// Set button background tint programmatically so it is compatible with pre-lollipop devices.
public static void setButtonBackgroundTintAppCompat(Button button, ColorStateList colorStateList){
    Drawable d = button.getBackground();
    if (button instanceof AppCompatButton) {
        // appcompat button replaces tint of its drawable background
        ((AppCompatButton)button).setSupportBackgroundTintList(colorStateList);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Lollipop button replaces tint of its drawable background
        // however it is not equal to d.setTintList(c)
        button.setBackgroundTintList(colorStateList);
    } else {
        // this should only happen if
        // * manually creating a Button instead of AppCompatButton
        // * LayoutInflater did not translate a Button to AppCompatButton
        d = DrawableCompat.wrap(d);
        DrawableCompat.setTintList(d, colorStateList);
        button.setBackgroundDrawable(d);
    }

}

Comment utiliser dans le code:

Utility.setButtonBackgroundTintAppCompat(myButton,
ContextCompat.getColorStateList(mContext, R.color.your_custom_color));

De cette façon, vous n'avez pas besoin de spécifier un ColorStateList si vous voulez juste changer la teinte d'arrière-plan et rien de plus, mais conserver les jolis effets de bouton et ce qui ne l'est pas.

Micro
la source
0

Je me suis mis android:textColorà@null mon bouton thème et ça aide.

styles.xml

<style name="Button.Base.Borderless" parent="Widget.AppCompat.Button.Borderless.Colored">
    <item name="android:textColor">@null</item>
</style>

some_layout.xml

<Button
    style="@style/Button.Base.Borderless"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hint" />

La couleur du texte du bouton est maintenant colorAccentdéfinie dansAppTheme

<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <item name="colorAccent">@color/colorAccent</item>
    <item name="borderlessButtonStyle">@style/Button.Base.Borderless</item>
    <item name="alertDialogTheme">@style/AlertDialog</item>
</style>
Denis Rybnikov
la source
0

si vous utilisez kotlin, pouvez-vous voir que tous les attributs de MaterialButton sont pris en charge. N'utilisez pas l'attribut android: background. MaterialButton gère son propre arrière-plan dessinable, et la définition d'un nouvel arrière-plan signifie que la couleur désactivée du bouton Matériau ne peut plus garantir que les nouveaux attributs qu'il introduit fonctionneront correctement. Si l'arrière-plan par défaut est modifié, le bouton Matériau ne peut garantir un comportement bien défini. À MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        buttonClick.setOnClickListener {
            (it as MaterialButton).apply {
                backgroundTintList = ColorStateList.valueOf(Color.YELLOW)
                backgroundTintMode = PorterDuff.Mode.SRC_ATOP
            }
        }
    }
}

À activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/constraintLayout"
    tools:context=".MainActivity">
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonNormal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="Material Button Normal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonTint"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:backgroundTint="#D3212D"
        android:text="Material Button Background Red"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonNormal" />
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonTintMode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:backgroundTint="#D3212D"
        android:backgroundTintMode="multiply"
        android:text="Tint Red + Mode Multiply"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonTint" />
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonClick"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="Click To Change Background"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonTintMode" />
</androidx.constraintlayout.widget.ConstraintLayout>

ressource: exemple de changement de couleur du bouton Matériau

Tienanhvn
la source
0

si vous voulez le faire via du code dans n'importe quelle couleur, utilisez ceci:

DrawableCompat.setTintList(button.getBackground(), ColorStateList.valueOf(yourColor));
Amir Hossein Ghasemi
la source