web-dev-qa-db-fra.com

Boutons de coloration dans Android avec Material Design et AppCompat

Avant que la mise à jour AppCompat ne soit publiée aujourd'hui, je pouvais changer la couleur des boutons dans Android L mais pas sur les versions antérieures. Après avoir inclus la nouvelle mise à jour AppCompat, je ne parviens pas à modifier la couleur de l'une ou l'autre version. Lorsque j'essaie, le bouton disparaît tout simplement. Est-ce que quelqu'un sait comment changer la couleur du bouton?

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

picture showing desired result

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 du styles.xml:

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

et de le faire dynamiquement:

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

De plus, j'ai changé le thème du thème de @Android:style/Theme.Material.Light.DarkActionBar à Theme.AppCompat.Light.DarkActionBar

238
mail929

Fixé officiellement dans la bibliothèque de support rév.22 (vendredi 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>
216
WindRider

Edit (22.06.2016):

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

Réponse originale:

Comme AppCompat ne prend pas encore en charge le bouton, vous pouvez utiliser xml comme arrière-plan. Pour ce faire, j’ai jeté un œil au code source de Android et trouvé les fichiers associés pour l’apparence des boutons de matériau.

1 - Regardez l’implémentation originale du bouton matériel de la source.

Regardez le btn_default_material.xml sur Android code source .

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 - Obtenir la forme du bouton de 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 de matériau

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

4 - Créer un autre fichier pouvant être dessiné pour les anciennes versions

Pour les anciennes versions, vous devriez avoir un autre dessin avec le même nom. Je mets directement les éléments en ligne au lieu de faire référence. Vous voudrez peut-être les référencer. Mais encore une fois, le plus important est les dimensions originales du bouton Matériau.

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, à l'exception de l'effet d'entraînement. Mais puisque vous fournissez des éléments dessinables pour différents états, ils répondent également aux événements tactiles (comme à l'ancienne).

148
eluleci

Cela a été amélioré dans la v23.0.0 de la bibliothèque AppCompat avec l’ajout de plus de thèmes, notamment

Widget.AppCompat.Button.Colored

Tout d’abord, incluez la dépendance appCompat si vous n’avez pas déjà

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

maintenant que vous devez utiliser la version 23 de l'application, vous devez é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>

Comme le thème de votre bouton est basé sur Widget.AppCompat.Button.Colored, la couleur du texte du bouton est par défaut blanche!

mais il semble y avoir un problème lorsque vous désactivez le bouton, celui-ci changera de couleur en gris clair, mais la couleur du texte restera blanche!

une solution de contournement consiste à définir spécifiquement la couleur du texte du bouton sur blanc! comme je l'ai fait dans le style 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" />

Etat désactivé Disabled state

État activé Enabled State

Modifier:

Pour ajouter <Button Android:theme="@style/BrandButtonStyle"/>

107
Muhammad Alfaifi

Dans Android Support Library 22.1.0, Google a activé la teinte Button. Une autre façon de personnaliser la couleur de fond du bouton consiste donc à utiliser l'attribut backgroundTint.

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" />
62
Manabu-GT

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

gonfler - XML

AppCompat Widget:

Android.support.v7.widget.AppCompatButton

Style AppCompat:

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

NB! Pour définir une couleur personnalisée en xml: utilisez attr: app au lieu de Android

(utilisez alt+enter ou déclarez xmlns:app="http://schemas.Android.com/apk/res-auto" pour 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"/>

o définissez-le par programme - Java

 ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));
40
TouchBoarder

Avec la dernière bibliothèque de support, vous pouvez simplement hériter de votre activité de AppCompatActivity. Elle gonflera ainsi votre Button comme AppCompatButton et vous donnera l’occasion de styliser la couleur de chaque bouton de la mise en page à l’aide de de Android:theme="@style/SomeButtonStyle", où SomeButtonStyle est:

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

Travaillé pour moi dans 2.3.7, 4.4.1, 5.0.2

25
Artem

si tu veux moins de style

enter image description here

ajoutez ce style à votre bouton

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

si tu veux ce style

enter image description here

ajouter le code ci-dessous

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

La réponse est dans THEME not style

Le problème est que la couleur du bouton est fidèle à la couleur colorButtonNormal du thème. J'ai essayé de changer le style de différentes façons 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 extension du style Button 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 la couleur de votre choix compatible avec le design des matériaux.

13
lonelyboycs

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 de votre choix avec une couleur différente, ce qui vous permet de personnaliser les couleurs de manière aléatoire.

4
xgc1986

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

Mise en page:

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

Pour ceux qui utilisent un ImageButton, 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"
    />
3
Micro

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

Comme

<style name="CustomButtonStyle" parent="Widget.AppCompat.Button.Colored">
      <item name="colorButtonNormal">@Android:color/white</item>
</style>
3
didi.yeah

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 .

1
kiruwka

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

Pour moi, le problème était que dans Android 5.0, le Android:colorButtonNormal n'avait aucun effet et, en fait, aucun élément du thème (comme Android:colorAccent), mais dans Android 4.4. 3, par exemple, a fait. Le projet était configuré avec compileSdkVersion et targetSdkVersion à 22, j'ai donc apporté tous les changements, comme le disait @Muhammad Alfaifi, mais j'ai finalement constaté que le problème était le buildToolsVersion, qui n'a pas été mis à jour. Une fois que j'ai changé pour 23.0.1, tout commence à fonctionner presque comme d'habitude. Maintenant, le Android:colorButtonNormal n'a toujours pas d'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 Android:theme=[...] du bouton n'avait également aucun effet.

1
Bianca D.

Je l'utilise. L'effet d'ondulation et l'ombre de clic de bouton fonctionnent.

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

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

MISE À JOUR

Utilisez la bibliothèque de support de conception (23.2.0) et appcompatwidgets comme ci-dessous.

Dans Android Bibliothèque de support 22.1:

Cette opération est effectuée automatiquement lors du gonflement des mises en page - en remplaçant Button par AppCompatButton, TextView par AppCompatTextView, etc., pour que chacun puisse prendre en charge la teinte. Dans cette version, ces widgets sensibles à la teinte sont désormais accessibles au public, ce qui vous permet de continuer à prendre en charge le support même si vous devez sous-classer l'un des widgets pris en charge.

La liste complète des widgets sensibles à la teinte:

AppCompatAutoCompleteTextView
AppCompatButton
AppCompatCheckBox
AppCompatCheckedTextView
AppCompatEditText
AppCompatMultiAutoCompleteTextView
AppCompatRadioButton
AppCompatRatingBar
AppCompatSpinner
AppCompatTextView

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

AppCompat (aussi appelé ActionBarCompat) a commencé comme portage de l'API ActionBar Android 4.0 pour les périphériques s'exécutant sur Gingerbread, fournissant une couche d'API commune au-dessus de l'implémentation transférée et de la structure. AppCompat v21 fournit une API et un ensemble de fonctionnalités mis à jour avec Android 5.0


1
Amit Vaghela

Une façon de retirer ceci vous permet de simplement pointer vers un style et PAS de thème TOUS les boutons de votre application.
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 add

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

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

Mon application a une minSdkVersion de 9 et tout fonctionnait auparavant.

Je ne sais pas pourquoi mais depuis que j'ai enlevé Android: avant le buttonStyle, il semble fonctionner à nouveau

maintenant = travail:

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

before = juste les boutons matériels gris:

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

Je n'ai pas de dossier spécial pour la version newver Android puisque mes boutons sont assez plats et qu'ils doivent être identiques à toutes les versions Android.

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

<item name="Android:imageButtonStyle">@style/ImageButtonmyTimeGreen</item>
0
stefan

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

J'utilise cette méthode utilitaire pour définir la teinte de fond d'un bouton. Cela fonctionne avec les appareils pré-Lollipop:

// 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 seulement changer la teinte de fond et rien de plus, mais conserver les jolis effets de bouton et ce qui ne l'est pas.

0
Micro

utilisez Android: backgroundTint = "@ color/customColor" et cela donnera une couleur personnalisée au bouton. C'est simple comme ça.

0
SuKu

Je règle Android:textColor sur @null dans le thème de mon bouton et cela 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" />

Maintenant, la couleur du texte du bouton est colorAccent définie dans AppTheme

<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>
0
Denis Rybnikov

Pour changer la couleur d'un seul bouton

ViewCompat.setBackgroundTintList(button, getResources().getColorStateList(R.color.colorId));
0
Jaydeep

Après 2 jours de recherche de réponses, la thématisation des boutons ne fonctionnait pas pour moi dans API <21.

Ma seule solution est de remplacer la teinte AppCompatButton non seulement par le thème de l'application de base "colorButtonNormal" mais également par 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 suit:

<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" />
0
Thomas G.