Boutons de coloration dans Android avec Material Design et AppCompat

Avant la AppCompat jour d’ AppCompat 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 d’AppCompat, je ne parviens pas à modifier la couleur de l’une ou l’autre version. Lorsque j’essaie, le bouton disparaît. Est-ce que quelqu’un sait comment changer la couleur du bouton?

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

photo 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 auparavant pour changer la couleur des boutons dans styles.xml :

 insert color here 

et le faire dynamicment:

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

J’ai aussi changé le parent du thème de @android:style/Theme.Material.Light.DarkActionBar à Theme.AppCompat.Light.DarkActionBar

Fixé officiellement dans la Support Library 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:

 @color/button_color 

v21 / theme.xml

 @color/button_color 

Edit (22.06.2016):

La bibliothèque Appcompat a commencé à prendre en charge les boutons matériels après la publication de 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:

Comme AppCompat ne supporte pas le bouton, vous pouvez utiliser XML comme arrière-plan. Pour ce faire, j’ai jeté un coup d’œil au code source de l’Android et j’ai trouvé les fichiers associés aux boutons de style.

1 – Regardez la mise en œuvre originale du bouton de matériau à partir de la source.

Consultez le fichier btn_default_material.xml sur le code source Android .

Vous pouvez copier le fichier dans le dossier drawable-v21 de vos projets. Mais ne touchez pas la couleur attr ici. Le fichier à modifier est le deuxième fichier.

drawable-v21 / custom_btn.xml

    

2 – Obtenez la forme du bouton de matériau d’origine

Comme vous vous en rendez compte, il existe une forme utilisée dans ce dessin que vous pouvez trouver dans ce fichier du code source .

       

3 – Obtenir les dimensions du bouton matériel

Et dans ce fichier, vous trouverez certaines dimensions du 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é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 articles en ligne au lieu de les référencer. Vous voudrez peut-être les référencer. Mais encore une fois, le plus important est la dimension originale du bouton matériel.

drawable / custom_btn.xml

                                   

Résultat

Votre bouton aura un effet d’entraînement sur les dispositifs Lollipop. Les anciennes versions auront exactement le même bouton, à l’exception de l’effet d’entraînement. Mais comme vous fournissez des tirables pour différents états, ils répondent également aux événements tactiles (comme à l’ancienne).

Cela a été amélioré dans la v23.0.0 de la bibliothèque AppCompat avec l’ajout de plusieurs 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

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

maintenant que vous devez utiliser la v23 de l’application compat, vous devez également cibler le SDK-v23!

  comstackSdkVersion = 23 targetSdkVersion = 23 

Dans vos values/theme

 @style/BrandButtonStyle 

Dans vos values/style

  

Dans vos values-v21/style

  

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

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 restra blanche!

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

Maintenant, vous pouvez simplement définir votre bouton et laisser AppCompat faire le rest 🙂

  

État handicapé État désactivé

État activé État activé

Dans Android Support Library 22.1.0, Google a rendu la teinte de Button consciente. Ainsi, une autre façon de personnaliser la couleur d’arrière-plan du bouton consiste à utiliser l’atsortingbut backgroundTint .

Par exemple,

  

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 dans xml: utilisez l’ app attr: au lieu d’ android

(utilisez alt+enter ou declare xmlns:app="http://schemas.android.com/apk/res-auto" pour utiliser l’ app )

app : backgroundTint = “@ color / your_custom_color”

Exemple:

  

ou définissez-le par programmation – JAVA

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

Avec la dernière bibliothèque de support, vous pouvez simplement hériter de votre activité à partir de AppCompatActivity , donc cela va gonfler votre Button tant AppCompatButton et vous donner la possibilité de AppCompatButton couleur de chaque bouton avec android:theme="@style/SomeButtonStyle" , où SomeButtonStyle est:

  

Travaillé pour moi en 2.3.7, 4.4.1, 5.0.2

si vous voulez ci-dessous le style

entrer la description de l'image ici

ajoutez ce style à votre bouton

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

si tu veux ce style

entrer la description de l'image ici

append le code ci-dessous

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

La réponse est dans THEME not style

Le problème est que la couleur du bouton est collée 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:

  

Utiliser ce thème dans le bouton

  

Le “AppTheme.Button” peut être n’importe quoi. Style de bouton comme ici J’utilise la couleur primaire pour la couleur du texte:

  

Et vous obtenez le bouton dans n’importe quelle couleur que vous voulez compatible avec la conception du matériau.

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

  

Vous n’avez pas besoin de créer un style pour chaque bouton souhaité avec une couleur différente, ce qui vous permet de personnaliser les couleurs de manière aléatoire

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

dans vos styles.xml

  

dans votre fichier de mise en page

  

Disposition:

  

styles.xml:

  

color / button_background_selector.xml:

      

color / button_text_selector.xml:

      

Pour ceux qui utilisent un ImageButton voici comment vous le faites:

Dans style.xml:

  

dans v21 / style.xml:

  

Ensuite, dans votre fichier de mise en page:

  

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’ondulation fonctionne;)

Comme

  

Si vous ne voulez que le bouton “Flat”, vous pouvez personnaliser leur arrière-plan en utilisant l’atsortingbut selectableItemBackground comme expliqué ici .

Pour moi, le problème était que dans Android 5.0, 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. Le projet a été configuré avec comstackSdkVersion et targetSdkVersion à 22, j’ai donc apporté toutes les modifications comme @Muhammad Alfaifi sugessted, mais à la fin, j’ai remarqué que le problème était la buildToolsVersion , qui n’a pas été mise à jour. Une fois que je suis passé à 23.0.1 , tout commence à fonctionner presque normalement. Maintenant, l’ 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 cette indication pourrait aider quelqu’un. Note: J’ai appliqué le style directement au bouton, car l’ android:theme=[...] du bouton n’a pas non plus d’effet.

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

   

Maintenant dans styles.xml add

   

Maintenant, dans votre disposition, pointez simplement sur le STYLE de votre bouton.

   

METTRE À JOUR

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

Dans Android Support Library 22.1 :

Cela se fait automatiquement lors du gonflage des mises en page – remplacement de Button avec AppCompatButton, TextView avec AppCompatTextView, etc. pour garantir que chacune puisse prendre en charge la teinte. Dans cette version, ces widgets compatibles avec les teintes sont désormais accessibles au public, ce qui vous permet de continuer à prendre en charge la teinte 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 du matériel pour les dispositifs pré-suceurs :

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


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:

  

Vous devez utiliser AppCompatButton pour activer les styles AppCompat:

  

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

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

Je ne sais pas pourquoi mais depuis que j’ai enlevé l’androïde: avant le bouton, le style semble fonctionner à nouveau

maintenant = travail:

@style/ButtonmyTime

avant = juste des boutons matériels gris:

@style/ButtonmyTime

Je n’ai pas de dossier spécial pour la version Android la plus récente, car mes boutons sont assez plats et ils devraient avoir la même apparence sur toutes les versions Android.

Peut-être que quelqu’un peut me dire pourquoi j’ai dû supprimer le “Android”: ImageButton fonctionne toujours avec “Android:”

 @style/ImageButtonmyTimeGreen 

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 consiste à remplacer la teinte AppCompatButton non seulement par le thème de base de l’application “colorButtonNormal”, mais aussi par la vue backgroundTint comme ceci:

 public class AppCompatColorButton extends AppCompatButton { public AppCompatColorButton(Context context) { this(context, null); } public AppCompatColorButton(Context context, AtsortingbuteSet attrs) { this(context, attrs, android.support.v7.appcompat.R.attr.buttonStyle); } public AppCompatColorButton(Context context, AtsortingbuteSet 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, AtsortingbuteSet 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.obtainStyledAtsortingbutes(attrs, new int[] { android.R.attr.backgroundTint }, defStyleAttr, 0); final int colorButtonNormal = a.getColor(0, themeColorButtonNormal);*/ TypedArray a = context.obtainStyledAtsortingbutes(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:

  

Pour changer la couleur d’un seul bouton

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

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 de fond d’un bouton. Cela fonctionne avec les dispositifs de pré-sucette:

 // 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 souhaitez simplement modifier la teinte de l’arrière-plan et rien de plus, tout en conservant les jolis effets de bouton et ce que vous n’êtes pas.

Une autre solution simple utilisant AppCompatButton

  

Je mets android:textColor à @null dans le thème de mon bouton et ça aide.

styles.xml

  

some_layout.xml

  

La couleur du bouton est colorAccent définie dans AppTheme

  

Je l’utilise Effet d’ondulation et bouton cliquez sur le travail de l’ombre.

style.xml

  

Bouton sur la mise en page: