Comment griser un bouton?

103

J'ai un bouton défini comme indiqué ci-dessous. Lorsque je veux le désactiver, je l'utilise my_btn.setEnabled(false), mais je voudrais également le griser. Comment puis je faire ça?

Merci

<Button android:id="@+id/buy_btn" style="@style/srp_button" />

style / bouton_srp

<style name="srp_button" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/btn_default</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textColor">#ffffff</item>
    <item name="android:textSize">14sp</item>
    <item name="android:typeface">serif</item>
    <item name="android:paddingLeft">30dp</item>
    <item name="android:paddingRight">30dp</item>
    <item name="android:paddingTop">5dp</item>
    <item name="android:paddingBottom">5dp</item>
</style>

drawable / btn_default.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/pink" />
    <corners android:radius="6dp" />
</shape>
juil
la source

Réponses:

57

Vous devez fournir 3 ou 4 états dans votre en btn_defaut.xmltant que sélecteur.

  1. État pressé
  2. État par défaut
  3. État de mise au point
  4. État activé (état désactivé avec indication fausse; voir les commentaires)

Vous fournirez l'effet et le contexte pour les états en conséquence.

Voici une discussion détaillée: Bouton Android standard avec une couleur différente

Adil Soomro
la source
Donc, pour le griser, je dois changer la couleur de l'arrière-plan ET la couleur du texte à l'état désactivé? Il n'y a aucun moyen d'ajouter simplement un premier plan transparent?
juillet
3
Oui! ce que vous fournissez pour android:state_disable="true"cela montrera l'état lorsque le bouton est désactivé, la manière facile et recommandée.
Adil Soomro
et où puis-je spécifier la couleur du texte pour l'état désactivé? Il semble que seul un arrière - plan peut être spécifié ... J'ai posé une nouvelle question pour que: stackoverflow.com/questions/8743584/...
juillet
17
Il n'y a pas android:state_disable="true", n'est-ce pas? Parlez-vous android:state_enabled="false"?
caw
@MarcoW .: oui, vous avez tout à fait raison. Toutes mes excuses pour le mauvais attribut.
Adil Soomro
172

Vous pouvez également le faire apparaître comme désactivé en définissant l'alpha (le rendant semi-transparent). Ceci est particulièrement utile si l'arrière-plan de votre bouton est une image et que vous ne souhaitez pas lui créer d'états.

button.setAlpha(.5f);
button.setClickable(false);

mise à jour: j'ai écrit la solution ci-dessus avant Kotlin et quand j'étais recrue. C'est plus une solution «rapide et sale», mais je ne la recommande pas dans un environnement professionnel.

Aujourd'hui, si je voulais une solution générique qui fonctionne sur n'importe quel bouton / vue sans avoir à créer une liste d'états, je créerais une extension Kotlin.

fun View.disable() {
    getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY)
    setClickable(false)
}

En Java, vous pouvez faire quelque chose de similaire avec une fonction util statique et il vous suffit de passer la vue en tant que variable. Ce n'est pas aussi propre mais ça marche.

Siavash
la source
4
J'avais lu que les appels à setAlpha coûtaient cher en CPU. Quelqu'un peut-il confirmer?
Ali Kazi
@AliKazi cela dépend du type de votre View. De ce post Google+ : "Si votre vue ne contient pas de commandes de dessin qui se chevauchent, elle setAlpha()est optimisée et nous modifions simplement les objets Paint pour appliquer l'alpha approprié. Cela se produit lorsque View.hasOverlappingRendering()renvoie true. Les ImageViews et TextViews sans arrière-plan dessinables sont des candidats courants pour cela optimisation. Si vous êtes dans cette situation, utilisez- setAlpha()en autant que vous le souhaitez. ".
Sufian
1
@Sufian Merci. Mais pour être plus sûr, je me suis appuyé sur un simple StateListDrawable pour chaque bouton. Comment j'ai fait cela, j'ai posté une nouvelle réponse. J'ai inclus des liens vers où j'ai appris que l'alpha est mauvais pour les performances.
Ali Kazi
Visually user-peufriendly
Farid
qui désactivent visuellement la vue. merci @Siavash
Akash Bisariya
54

La solution la plus simple consiste à définir le filtre de couleur sur l'image d'arrière-plan d'un bouton comme je l'ai vu ici

Vous pouvez faire comme suit:

if ('need to set button disable')
    button.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
else
    button.getBackground().setColorFilter(null);

J'espère que j'ai aidé quelqu'un ...

Boisé
la source
J'aime mieux cette approche. Merci!
attraper le
2
Cette approche a du potentiel, mais la couleur qui en résulte n'est pas toujours ce que vous pensez qu'elle sera. Par exemple, un bouton orange avec la couleur grise multipliée donne une couleur rouge foncé, et non une orange fanée.
Someone Somewhere
4
peut-être Mode.SRC_INdevrait être utilisé à la place de la multiplication. Voir stackoverflow.com/a/17112876/550471
Someone Somewhere
Cela fonctionne, mais deux couleurs une fois mélangées se transforment en une autre couleur
Shamsul Arefin Sajib
Impressionnant! si propre.
Milind Chaudhary
21

Toutes les réponses données fonctionnent bien, mais je me souviens avoir appris que l'utilisation de setAlpha peut être une mauvaise idée en termes de performances (plus d'informations ici ). Donc, créer un StateListDrawable est une meilleure idée pour gérer l'état désactivé des boutons. Voici comment:

Créez un fichier XML btn_blue.xml dans le dossier res / drawable:

<!-- Disable background -->
<item android:state_enabled="false"
      android:color="@color/md_blue_200"/>

<!-- Enabled background -->
<item android:color="@color/md_blue_500"/>

Créer un style de bouton dans res / values ​​/ styles.xml

<style name="BlueButton" parent="ThemeOverlay.AppCompat">
      <item name="colorButtonNormal">@drawable/btn_blue</item>
      <item name="android:textColor">@color/md_white_1000</item>
</style>

Ensuite, appliquez ce style à votre bouton:

<Button
     android:id="@+id/my_disabled_button"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:theme="@style/BlueButton"/>

Maintenant quand tu appelles btnBlue.setEnabled(true) OU, btnBlue.setEnabled(false)les couleurs de l'état changent automatiquement.

Ali Kazi
la source
12

Définissez Clickable sur false et modifiez la couleur du fond comme suit:

callButton.setClickable(false);
callButton.setBackgroundColor(Color.parseColor("#808080"));
Saty
la source
12

Vous devez créer un fichier XML pour le bouton désactivé ( drawable / btn_disable.xml )

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/grey" />
    <corners android:radius="6dp" />
</shape>

Et créez un sélecteur pour le bouton ( drawable / btn_selector.xml )

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/btn_disable" android:state_enabled="false"/>
    <item android:drawable="@drawable/btn_default" android:state_enabled="true"/>
    <item android:drawable="@drawable/btn_default" android:state_pressed="false" />

</selector>

Ajoutez le sélecteur à votre bouton

<style name="srp_button" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/btn_selector</item>
</style>
Willy Chen
la source
2
Button button = (Button)findViewById(R.id.buy_btn);
button.setEnabled(false);
Léon van Noord
la source
13
Cela ne répond pas à la question.
Quality Catalyst
1

J'ai utilisé ce code pour cela:

ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
profilePicture.setColorFilter(filter);
Dominik
la source
0

J'ai essayé les solutions ci-dessus mais aucune d'entre elles ne semblait fonctionner pour moi. Je suis allé avec l'option suivante:

<!-- button_color_selector.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorAccent" android:state_enabled="true"/>
    <item android:color="@color/colorAccentLight" android:state_enabled="false"/>
</selector>
<com.google.android.material.button.MaterialButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:backgroundTint="@color/button_color_selector"
                .../>
André Ramon
la source