web-dev-qa-db-fra.com

BackgroundTint de Lollipop n'a aucun effet sur un bouton

J'ai un bouton dans mon activité et j'aimerais qu'il ait la couleur d'accent de mon thème . Au lieu de créer mes propres dessinables comme nous devions le faire avant Lollipop, naturellement, j'aimerais utiliser le nouvel attribut backgroundTint .

<Button
    Android:id="@+id/btnAddCode"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:backgroundTint="@color/accent"
    Android:text="@string/addressInfo_edit_addCode" />

Malheureusement, cela n’a aucun effet, le bouton reste gris.

J'ai essayé différentes valeurs pour backgroundTintMode, ce qui n'a rien changé.

J'ai aussi essayé de le faire par programme dans mon activité, ce qui n'a rien changé.

addCodeView.findViewById(R.id.btnAddCode).setBackgroundTintList(
     getResources().getColorStateList(R.color.accent));

Pourquoi ma teinte est-elle ignorée?

EDIT: Juste pour clarifier, je teste effectivement sur un périphérique Lollipop . Les autres widgets (par exemple, EditText) sont correctement et automatiquement teintés.

72
BoD

Testé sur les API 19 à 27

<?xml version="1.0" encoding="utf-8"?>
  <Android.support.v7.widget.AppCompatButton 
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    style="@style/Widget.AppCompat.Button.Colored"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="@string/retry"
    Android:textColor="@Android:color/white"
    app:backgroundTint="@Android:color/holo_red_dark" />

produit une sortie sous forme de - 

 enter image description here

10
Sahitya Pasnoor

Les mauvaises nouvelles

Comme dit BoD, il ne sert à rien de teinter l'arrière-plan d'un bouton dans Lollipop 5.0 (API de niveau 21).

La bonne nouvelle

Lollipop 5.1 (niveau 22 de l'API) semble avoir résolu ce problème en modifiant btn_mtrl_default_shape.xml (entre autres fichiers): https://Android.googlesource.com/platform/frameworks/base/+/6dfa60f33ca6018959ebff1efde2db7d2a2) F0

La bonne nouvelle

La nouvelle bibliothèque de prise en charge (version 22.1+) ajoute la prise en charge de la coloration rétro-compatible à de nombreux composants, notamment AppCompatButton !

Malheureusement, la propriété Android:backgroundTint ne fonctionne toujours pas (peut-être que je fais quelque chose de mal). Vous devez donc définir la variable ColorStateList dans le code, en utilisant setSupportBackgroundTintList() . Ce serait vraiment agréable de voir Android:backgroundTint pris en charge à l'avenir. Mise à jour: Marcio Granzotto a déclaré que app:backgroundTint fonctionne sur AppCompatButton! Notez que c'est app:, pas Android:, car c'est dans l'application/bibliothèque.

<LinearLayout 
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" >

    <AppCompatButton
        Android:id="@+id/mybutton"
        Android:layout_width="wrap_content" Android:layout_height="wrap_content"
        Android:text="Testing, testing"
        app:backgroundTint="#ff00ff"/>

</LinearLayout>

Votre activité va automatiquement gonfler une AppCompatButton au lieu de la Button normale si vous la laissez hériter de AppCompatActivity.

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AppCompatButton v = (AppCompatButton) findViewById(R.id.mybutton);
        ColorStateList csl = new ColorStateList(new int[][]{new int[0]}, new int[]{0xffffcc00});
        v.setSupportBackgroundTintList(csl);
    }
}

Vous devriez bien sûr obtenir la variable ColorStateList à partir d’une ressource couleur, mais j’étais paresseux, alors ...

Oh, et n'oubliez pas de baser le thème de votre application sur l'un des thèmes Theme.AppCompat; sinon, les vues des compatriotes seront très tristes ...;)

Cela a fonctionné sur les versions 2.3.7 (Gingerbread MR1) et 5.0 (Lollipop 'Classic').

111
Snild Dolkow

Il semble que teinter une ondulation dessinable n’a pas de sens (et l’arrière-plan par défaut d’un bouton est une ondulation dessinable).

En fait, après avoir examiné le bouton dessinable par défaut de la plate-forme, j'ai trouvé la manière "correcte" de procéder: Vous devez définir ceci dans votre thème: 

    <item name="Android:colorButtonNormal">@color/accent</item>

(Bien sûr, ce n'est que pour le niveau 21+.)

Attention: comme ceci est défini dans un thème, cela utilisera la couleur donnée pour tous les boutons (au moins tous les boutons des activités utilisant ce thème.)

En prime, vous pouvez également changer la couleur de l'ondulation en définissant ceci:

    <item name="Android:colorControlHighlight">@color/accent_ripple</item>
29
BoD

Pour résoudre les problèmes liés à la teinte sur Android 5.0.x, j'utilise quelque chose comme ceci:

public static void setButtonTint(Button button, ColorStateList tint) {
    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Lollipop && button instanceof AppCompatButton) {
        ((AppCompatButton) button).setSupportBackgroundTintList(tint);
    } else {
        ViewCompat.setBackgroundTintList(button, tint);
    }
}

Il utilise la méthode de support uniquement pour l'API 21 et le ViewCompat pour tous les autres cas.

22
GUG

Utilisez simplement app:backgroundTint au lieu de Android:backgroundTint, la teinte prendra effet sous Lollipop. La raison est AppCompatActivity, utilisez AppCompatViewInflater pour modifier automatiquement Button ou TextView en AppCompatButton ou AppCompatTextView, puis app:backgroundTint prend effet.

 enter image description here

Dans mon projet je l'ai utilisé, cela a fonctionné.

19
drakeet

Je le fais habituellement de manière dynamique en utilisant PorterDuff:

mbutton = (Button) findViewById(R.id.mybutton);
mbutton.getBackground().setColorFilter(anycolor, PorterDuff.Mode.MULTIPLY);

Vous pouvez vérifier les différents modes de fusion ici et les exemples de Nice ici .

19
Carlos Borau

Je pense que vous devez avoir Android:background défini pour que Android:backgroundTint fonctionne.

Pour être plus précis, je suppose que vous ne pouvez pas backgroundTint l’arrière-plan du bouton par défaut des thèmes de matériaux, qui est défini comme un RippleDrawable.

9
natario

Un problème similaire a été signalé sur google https://code.google.com/p/Android/issues/detail?id=201873

Mais après la sortie de la bibliothèque de support Android, révision 23.2.1 (mars 2016) Ce bogue est résolu.

Issue: FloatingActionButton.setBackgroundTintList (teinte @Nullable ColorStateList) ne change plus la couleur d'arrière-plan

mettre à jour la bibliothèque de support à Android Support Library to 23.2.1

Utilisez design support library (23.2.1) et appcompatwidgets comme ci-dessous

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

AppCompat (aka ActionBarCompat) a commencé comme un backport du API ActionBar Android 4.0 pour les appareils fonctionnant sur Gingerbread, fournir une couche d'API commune au-dessus de la mise en œuvre rétroportée et la mise en œuvre du cadre. AppCompat v21 fournit une API et ensemble de fonctionnalités mis à jour avec Android 5.0


Bibliothèque de support Android 22.1:

La possibilité de colorer automatiquement les widgets lors de l'utilisation d'AppCompat est incroyablement utile pour garder une marque forte et une cohérence tout au long de votre application. Ceci est fait automatiquement lors du gonflage des layouts - en remplaçant Button par AppCompatButton, TextView par AppCompatTextView, etc. pour que chacun puisse prendre en charge la teinte. Dans Dans cette version, ces widgets sensibles à la teinte sont désormais accessibles au public, vous permettant de continuer à colorer le support même si vous devez sous-classer un des widgets pris en charge.

3
Amit Vaghela

Si nous examinons le code source de Support Library, nous voyons qu'il teint normalement les boutons connus, mais si nous modifions la forme de notre bouton (j'ai un bouton rond), la teinte ne fonctionne pas correctement dans api <= 21 .Nous pouvons également constater que TintManager est devenu une classe publique (appcompat-v7: 23.1.1). Nous pouvons donc utiliser ColorStateList à partir de la forme de bouton par défaut (ce qui est coloré dans la version 5.0) pour le thème actuel tableau de couleurs):

    Context c = ...; // activity
    AppCompatButton ab = ...; // your button
    // works ok in 22+:
    if (Build.VERSION.SDK_INT <= 21) {
        // default appcompat button, that is tinted ok with current theme colors "abc_btn_default_mtrl_shape":
        // ColorStateList tint = TintManager.get(c).getTintList(R.drawable.abc_btn_default_mtrl_shape);
        // Appcompat 23.2 change:
        ColorStateList tint = AppCompatDrawableManager.get().getTintList(c, R.drawable.abc_btn_default_mtrl_shape);
        ab.setSupportBackgroundTintList(tint);
        }
2
Pavel Biryukov

vous pouvez utiliser backgroundTint<Android.support.design.button.MaterialButton avec "com.Android.support:design:28.0.0-rc01" version

0
Zafer Celaloglu

Sachez que la bibliothèque la plus mise à jour de recyclerview peut également être à l'origine de ce bogue.

Cette commande 

  sendBtnView.setBackgroundTintList(colorState)

fonctionnait parfaitement dans le passé, mais arrêtez de travailler pour moi. Après des recherches, il s’avère que la cause est la bibliothèque qui a été ajoutée aux dépendances:

  compile 'com.Android.support:recyclerview-v7:+'

J'ai donc essayé de le changer en 23.02.1 comme il était recommandé ici dans le post Amit Vaghela . J'ai changé en

  compile  'com.Android.support:recyclerview-v7:23.02.1'

Mais gradle error dit recyclerview lib n’a pas cette version (23.02.1) (gradle n’a pas pu le trouver dans Jcenter raw.github ou repo). 

Ensuite, parce que je savais que la commande setBackgroundTintList fonctionnait bien dans le passé avec la version 22.02.0 'dans toutes les autres bibliothèques que j'ai dans les dépendances Gradle. alors je le change en:

compile   'com.Android.support:recyclerview-v7:22.02.0'

Et maintenant ça marche encore.

0
Udi Reshef

Il suffit d'utiliser app: backgroundTint au lieu d'Android: backgroundTint

0
Smirnov Sergey

Parce que l'attribut backgroundTint n'est utilisé que dans les API de niveau 21 et supérieur

0
fedache

Je ne sais pas si cela est recommandé mais vous pouvez essayer ceci:

Drawable newDrawable = mBtnAction.getBackground();  // obtain Bg drawable from the button as a new drawable
DrawableCompat.setTint(newDrawable, mActivity.getHomeTobBarBGColor());  //set it's tint
mBtnAction.setBackground(newDrawable);  //apply back to button

De manière générale, cela fonctionne. Essayé ViewCompat mais cela ne semble pas fonctionner correctement.

0
sud007