Question Bouton Android standard avec une couleur différente


J'aimerais changer légèrement la couleur d'un bouton Android standard afin de mieux correspondre à l'image de marque d'un client.

Le meilleur moyen que j'ai trouvé pour le faire est de changer Buttonest tirable à l 'drawable suivant situé dans res/drawable/red_button.xml:

<?xml version="1.0" encoding="utf-8"?>    
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/red_button_pressed" />
    <item android:state_focused="true" android:drawable="@drawable/red_button_focus" />
    <item android:drawable="@drawable/red_button_rest" />
</selector>

Mais cela nécessite que je crée trois drawables différents pour chaque bouton que je veux personnaliser (un pour le bouton au repos, un pour le focus et un autre pour le bouton). Cela semble plus compliqué et non-DRY que j'ai besoin.

Tout ce que je veux vraiment faire est d'appliquer une sorte de transformée de couleur au bouton. Existe-t-il un moyen plus simple de modifier la couleur d'un bouton que je ne le fais?


688
2017-10-05 18:23


origine


Réponses:


J'ai découvert que tout cela peut être fait dans un fichier assez facilement. Mettez quelque chose comme le code suivant dans un fichier nommé custom_button.xml puis définissez background="@drawable/custom_button" dans votre vue de bouton:

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" >
        <shape>
            <gradient
                android:startColor="@color/yellow1"
                android:endColor="@color/yellow2"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

    <item android:state_focused="true" >
        <shape>
            <gradient
                android:endColor="@color/orange4"
                android:startColor="@color/orange5"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

    <item>        
        <shape>
            <gradient
                android:endColor="@color/blue2"
                android:startColor="@color/blue25"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>

694
2017-11-13 00:19



Suite à la réponse de Tomasz, vous pouvez également programmer la nuance de l'ensemble du bouton en utilisant le mode multiplier PorterDuff. Cela va changer la couleur du bouton plutôt que la teinte.

Si vous commencez avec un bouton gris ombré standard:

button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);

vous donnera un bouton rouge ombré,

button.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);

vous donnera un bouton vert ombré etc., où la première valeur est la couleur au format hexadécimal.

Cela fonctionne en multipliant la valeur actuelle de couleur de bouton par votre valeur de couleur. Je suis sûr que vous pouvez faire beaucoup plus avec ces modes.


297
2017-08-15 01:35



Mike, vous pourriez être intéressé par les filtres de couleur.

Un exemple:

button.getBackground().setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0xFFAA0000));

essayez ceci pour obtenir la couleur que vous voulez.


144
2017-08-09 23:28



C'est ma solution qui fonctionne parfaitement de l'API 15. Cette solution conserve tous les effets de clic de bouton par défaut, comme le matériel RippleEffect. Je ne l'ai pas testé sur les API inférieures, mais cela devrait fonctionner.

Tout ce que vous devez faire, c'est:

1) Créer un style qui ne change que colorAccent:

<style name="Facebook.Button" parent="ThemeOverlay.AppCompat">
    <item name="colorAccent">@color/com_facebook_blue</item>
</style>

Je recommande d'utiliser ThemeOverlay.AppCompat ou votre principale AppTheme en tant que parent, pour garder le reste de vos styles.

2) Ajoutez ces deux lignes à votre button widget:

style="@style/Widget.AppCompat.Button.Colored"
android:theme="@style/Facebook.Button"

Parfois, votre nouvelle colorAccent ne s'affiche pas dans Android Studio Preview, mais lorsque vous lancez votre application sur le téléphone, la couleur sera modifiée.


Exemple de widget de bouton

<Button
    android:id="@+id/sign_in_with_facebook"
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="@string/sign_in_facebook"
    android:textColor="@android:color/white"
    android:theme="@style/Facebook.Button" />

Sample Button with custom color


71
2017-07-19 20:42



Vous pouvez maintenant utiliser aussi appcompat-v7 AppCompatButton avec le backgroundTint attribut:

<android.support.v7.widget.AppCompatButton
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:backgroundTint="#ffaa00"/>

44
2018-01-16 20:20



J'aime la suggestion de filtre de couleur dans les réponses précédentes de @conjugatedirection et @Tomasz; Cependant, j'ai trouvé que le code fourni jusqu'ici n'était pas aussi facilement appliqué que je m'attendais.

Premièrement, il n'a pas été mentionné  appliquer et effacer le filtre de couleur. Il est possible qu'il y ait d'autres bons endroits pour cela, mais ce qui m'est venu à l'esprit était un OnTouchListener.

D'après ma lecture de la question initiale, la solution idéale serait celle qui n'implique aucune image. La réponse acceptée en utilisant custom_button.xml de @emmby est probablement un meilleur ajustement que les filtres de couleur si c'est votre objectif. Dans mon cas, je commence avec une image png d'un concepteur d'interface utilisateur de ce que le bouton est censé ressembler. Si je règle l'arrière-plan du bouton sur cette image, le retour de surbrillance par défaut est complètement perdu. Ce code remplace ce comportement par un effet d'assombrissement programmatique.

button.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 0x6D6D6D sets how much to darken - tweak as desired
                setColorFilter(v, 0x6D6D6D);
                break;
            // remove the filter when moving off the button
            // the same way a selector implementation would 
            case MotionEvent.ACTION_MOVE:
                Rect r = new Rect();
                v.getLocalVisibleRect(r);
                if (!r.contains((int) event.getX(), (int) event.getY())) {
                    setColorFilter(v, null);
                }
                break;
            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                setColorFilter(v, null);
                break;
        }
        return false;
    }

    private void setColorFilter(View v, Integer filter) {
        if (filter == null) v.getBackground().clearColorFilter();
        else {
            // To lighten instead of darken, try this:
            // LightingColorFilter lighten = new LightingColorFilter(0xFFFFFF, filter);
            LightingColorFilter darken = new LightingColorFilter(filter, 0x000000);
            v.getBackground().setColorFilter(darken);
        }
        // required on Android 2.3.7 for filter change to take effect (but not on 4.0.4)
        v.getBackground().invalidateSelf();
    }
});

J'ai extrait ceci comme une classe séparée pour l'application à plusieurs boutons - montrés comme classe interne anonyme juste pour avoir l'idée.


22
2018-06-17 10:56



Si vous créez des boutons de couleur avec XML, vous pouvez rendre le code un peu plus clair en spécifiant l'état focalisé et enfoncé dans un fichier séparé et réutilisez-les. Mon bouton vert ressemble à ceci:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_focused="true" android:drawable="@drawable/button_focused"/>
    <item android:state_pressed="true" android:drawable="@drawable/button_pressed"/>

    <item>
        <shape>
            <gradient android:startColor="#ff00ff00" android:endColor="#bb00ff00" android:angle="270" />
            <stroke android:width="1dp" android:color="#bb00ff00" />
            <corners android:radius="3dp" />
            <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
        </shape>
    </item>

</selector>

16
2017-12-16 11:23



La solution la plus courte qui fonctionne avec n'importe quelle version d'Android:

<Button
     app:backgroundTint="@color/my_color"

Notes / Exigences:

  • Utilisez le app: espace de noms et ne pas la android: espace de noms!
  • Version d'appcompat> 24.2.0

    dépendances {     compile 'com.android.support:appcompat-v7:25.3.1' }

Explication: enter image description here


10
2018-05-04 12:21



J'utilise cette approche

style.xml

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:colorPrimaryDark">#413152</item>
    <item name="android:colorPrimary">#534364</item>
    <item name="android:colorAccent">#534364</item>
    <item name="android:buttonStyle">@style/MyButtonStyle</item>
</style>

<style name="MyButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="android:colorButtonNormal">#534364</item>
    <item name="android:textColor">#ffffff</item>
</style>

Comme vous pouvez le voir ci-dessus, j'utilise un style personnalisé pour mon bouton. La couleur du bouton correspond à la couleur d'accent. Je trouve que c'est une bien meilleure approche que de android:background comme je ne perdrai pas l'effet d'entraînement que Google fournit.


9
2017-11-05 13:23