Bouton Android Standard avec une couleur différente

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

le meilleur moyen que j'ai trouvé pour le faire jusqu'à présent est de changer le Button 's tirable à la suivante 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 faire cela exige que je crée en fait trois tiroirs différents pour chaque bouton que je veux personnaliser (un pour le bouton au repos, un lorsque concentré, et un quand la touche est pressée). Cela semble plus compliqué et non sec.

Tout ce que je veux vraiment faire est d'appliquer une sorte de transformation de couleur sur le bouton. Y a-t-il un moyen plus facile de changer la couleur d'un bouton que ce que je fais?

694
demandé sur Catalina 2009-10-05 22:23:30

18 réponses

j'ai découvert que cela peut être fait dans un fichier assez facilement. Mettez quelque chose comme le code suivant dans un fichier nommé custom_button.xml et puis mettez 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>
698
répondu emmby 2010-07-22 12:59:16

suite à la réponse de Tomasz, vous pouvez également programmatiquement régler l'ombre du bouton entier en utilisant le mode de multiplication PorterDuff. Cela changera la couleur du bouton plutôt que la teinte.

si vous commencez par un bouton standard en gris:

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., dans lequel la première valeur est la couleur en hexadécimal format.

il fonctionne en multipliant la valeur de couleur du bouton courant par votre valeur de couleur. Je suis sûr qu'il y est aussi beaucoup plus que vous pouvez faire avec ces modes.

298
répondu conjugatedirection 2010-08-15 02:41:42

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

un exemple:

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

essayez ceci pour obtenir la couleur que vous voulez.

144
répondu Tomasz 2012-09-05 06:38:29

C'est ma solution qui fonctionne parfaitement à partir de 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 APIs inférieurs, mais ça devrait marcher.

Tout ce que vous devez faire, est:

1) Créer un style qui change seulement 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 principal AppTheme comme 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 nouveau colorAccent n'apparaît pas dans Android Studio Preview, mais lorsque vous lancez votre application sur le téléphone, la couleur sera changé.


Exemple de widget 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

75
répondu RediOne1 2017-08-07 05:03:14

vous pouvez maintenant aussi utiliser l'attribut backgroundTint D'appcompat-v7 AppCompatButton avec l'attribut backgroundTint :

<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"/>
48
répondu Nilhcem 2018-07-03 05:19:45

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

tout d'abord, il n'a pas été mentionné à appliquer et nettoyer le filtre couleur. Il est possible qu'il y ait d'autres bons endroits pour le faire, mais ce qui m'est venu à l'esprit était un Ontouchtener .

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 couleur si c'est votre but. Dans mon cas, je commence avec une image png d'un concepteur D'UI de ce que le bouton est censé ressembler. Si je mets le bouton background sur cette image, le retour de surlignage par défaut est complètement perdu. Ce code remplace ce comportement par un effet d'obscurcissement 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é comme classe interne anonyme juste pour obtenir l'idée.

22
répondu Stan Kurdziel 2012-06-17 11:07:25

si vous faites des boutons de couleur avec XML, vous pouvez rendre le code un peu plus propre en spécifiant l'état focalisé et pressé dans un fichier séparé et les réutiliser. 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
répondu haemish 2011-12-16 11:23:24

la solution la plus courte qui fonctionne avec N'importe quelle version Android:

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

Notes / Exigences :

  • utilisez l'espace de noms app: et pas L'espace de noms android: !
  • appcompat version > 24.2.0

    dépendances { compiler 'com.Android.support: appcompat-v7: 25.3.1" }

explication : enter image description here

10
répondu user1185087 2017-05-04 12:27:59

j'utilise cette approche

de 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 de l'accent. Je trouve que c'est une bien meilleure approche que de définir android:background que je ne perdrai pas l'effet d'ondulation fournit Google.

9
répondu Kelok Chan 2015-11-05 13:23:43

il y a une voie beaucoup plus facile maintenant: android-holo-colors.com

il vous permettra de changer les couleurs de tous les Holo drawables (boutons, spinners, ...) facilement. Vous sélectionnez la couleur et téléchargez ensuite un fichier zip contenant des tirables pour toutes les résolutions.

8
répondu Dalmas 2013-06-14 12:45:53

utilisez - le de cette façon:

buttonOBJ.getBackground().setColorFilter(Color.parseColor("#YOUR_HEX_COLOR_CODE"), PorterDuff.Mode.MULTIPLY);
8
répondu IntelliJ Amiya 2017-02-14 05:08:40

dans <Button> utiliser android:background="#33b5e5" . ou mieux android:background="@color/navig_button"

4
répondu lalitm 2014-03-01 06:31:52

le DroidUX la bibliothèque de composants a un ColorButton widget dont la couleur peut être changée facilement, à la fois via la définition xml et programmatiquement au moment de l'exécution, de sorte que vous pouvez même laisser l'utilisateur pour régler la couleur du bouton/Thème si votre application le permet.

3
répondu Ricky Lee 2011-08-05 12:53:26

vous pouvez également utiliser cet outil en ligne pour personnaliser votre bouton http://angrytools.com/android/button / et utilisez android:background="@drawable/custom_btn" pour définir le bouton personnalisé dans votre mise en page.

3
répondu JRE.exe 2016-09-27 13:09:11

vous pouvez définir le thème de votre bouton à ce

<style name="AppTheme.ButtonBlue" parent="Widget.AppCompat.Button.Colored">
 <item name="colorButtonNormal">@color/HEXColor</item>
 <item name="android:textColor">@color/HEXColor</item>
</style>
2
répondu Manoj Bhadane 2016-10-07 10:30:57

un moyen facile est de définir juste une classe de bouton personnalisé qui accepte toutes les propriétés que vous désirez comme le rayon, le gradient, la couleur pressée, la couleur normale, etc. et puis utilisez simplement cela dans vos mises en page XML au lieu de configurer L'arrière-plan en utilisant XML. Un échantillon est ici

C'est extrêmement utile si vous avez beaucoup de boutons avec les mêmes propriétés de rayon, choisis la couleur etc. Vous pouvez personnaliser votre bouton hérité pour gérer ces propriétés supplémentaires.

résultat (Aucun sélecteur D'arrière-plan n'a été utilisé).

Bouton Normal

Normal Image

Bouton Pressé

enter image description here

1
répondu redDragonzz 2015-01-13 14:13:11

la façon dont je fais un bouton stylé différent qui fonctionne assez bien est de sous-classer l'objet du bouton et d'appliquer un filtre couleur. Cela permet également de gérer les États activés et désactivés en appliquant un alpha au bouton.

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.Button;

public class DimmableButton extends Button {

    public DimmableButton(Context context) {
        super(context);
    }

    public DimmableButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DimmableButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void setBackgroundDrawable(Drawable d) {
        // Replace the original background drawable (e.g. image) with a LayerDrawable that
        // contains the original drawable.
        DimmableButtonBackgroundDrawable layer = new DimmableButtonBackgroundDrawable(d);
        super.setBackgroundDrawable(layer);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void setBackground(Drawable d) {
        // Replace the original background drawable (e.g. image) with a LayerDrawable that
        // contains the original drawable.
        DimmableButtonBackgroundDrawable layer = new DimmableButtonBackgroundDrawable(d);
        super.setBackground(layer);
    }

    /**
     * The stateful LayerDrawable used by this button.
     */
    protected class DimmableButtonBackgroundDrawable extends LayerDrawable {

        // The color filter to apply when the button is pressed
        protected ColorFilter _pressedFilter = new LightingColorFilter(Color.LTGRAY, 1);
        // Alpha value when the button is disabled
        protected int _disabledAlpha = 100;
        // Alpha value when the button is enabled
        protected int _fullAlpha = 255;

        public DimmableButtonBackgroundDrawable(Drawable d) {
            super(new Drawable[] { d });
        }

        @Override
        protected boolean onStateChange(int[] states) {
            boolean enabled = false;
            boolean pressed = false;

            for (int state : states) {
                if (state == android.R.attr.state_enabled)
                    enabled = true;
                else if (state == android.R.attr.state_pressed)
                    pressed = true;
            }

            mutate();
            if (enabled && pressed) {
                setColorFilter(_pressedFilter);
            } else if (!enabled) {
                setColorFilter(null);
                setAlpha(_disabledAlpha);
            } else {
                setColorFilter(null);
                setAlpha(_fullAlpha);
            }

            invalidateSelf();

            return super.onStateChange(states);
        }

        @Override
        public boolean isStateful() {
            return true;
        }
    }

}
0
répondu Matthew Cawley 2016-07-25 08:48:21

les valeurs de\styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

<style name="RedAccentButton" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">#ff0000</item>
</style>

puis:

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="text" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="text" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="text"
    android:theme="@style/RedAccentButton" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="text"
    android:theme="@style/RedAccentButton" />

result

0
répondu Milan Hlinák 2017-04-06 17:37:10