web-dev-qa-db-fra.com

Bouton standard Android de couleur différente

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

Le meilleur moyen que j’ai trouvé de faire cela jusqu’à présent est de changer le tirage de Button en tirable 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 pour cela, il faut que je crée trois tirables différents pour chaque bouton que je souhaite personnaliser (un pour le bouton au repos, un lorsque vous avez le focus et un lorsque vous appuyez dessus). Cela semble plus compliqué et non-sec que j'ai besoin.

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

725
emmby

J'ai découvert que tout cela peut être fait dans un seul 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 affichage 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>
717
emmby

Pour faire suite à la réponse de Tomasz, vous pouvez également définir par programmation la nuance de tout le bouton à l’aide du mode multiplicateur PorterDuff. Cela changera la couleur du bouton plutôt que la teinte.

Si vous commencez avec un bouton ombré gris standard:

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

vous donnera un bouton ombré rouge,

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

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

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

306
conjugatedirection

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.

148
Tomasz

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

Tout ce que vous devez faire, c'est:

1) Créez 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 principal AppTheme comme parent pour conserver le reste de vos styles.

2) Ajoutez ces deux lignes à votre widget button:

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 change.


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

83
RediOne1

Vous pouvez maintenant également utiliser AppCompatButton de appcompat-v7 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"/>
58
Nilhcem

J'aime la suggestion de filtre de couleur dans les réponses précédentes de @conjugatedirection et @Tomasz; Cependant, j’ai constaté que le code fourni jusqu’à présent n’était pas aussi facile à appliquer que prévu.

Premièrement, il n'a pas été mentionné appliquer et effacer le filtre de couleur. Il est possible qu'il existe d'autres bons endroits pour le faire, 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 une solution sans images. La réponse acceptée en utilisant custom_button.xml de @emmby est probablement plus adaptée que les filtres de couleur si tel est votre objectif. Dans mon cas, je commence avec une image png d'un concepteur d'interface utilisateur indiquant à quoi le bouton est censé ressembler. Si je règle l'arrière-plan du bouton sur cette image, le retour d'informations 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 en tant que classe distincte pour l'application à plusieurs boutons - indiqué comme classe interne anonyme juste pour comprendre l'idée.

22
Stan Kurdziel

Si vous créez des boutons de couleur avec XML, vous pouvez rendre le code un peu plus propre en spécifiant les états focalisé et enfoncé dans un fichier séparé et en les réutilisant. 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
haemish

La solution la plus courte qui fonctionne avec toutes les versions de Android:

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

Notes/Conditions requises :

  • Utilisez le app: espace de nom et pas le Android: espace de nom!
  • appcompat version> 24.2.0

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

Explication : enter image description here

12
user1185087

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 cette approche est bien meilleure que de définir Android:background, car je ne perdrai pas l'effet d'entraînement que Google fournit.

9
Kelok Chan

Utilisez-le de cette façon:

buttonOBJ.getBackground().setColorFilter(Color.parseColor("#YOUR_HEX_COLOR_CODE"), PorterDuff.Mode.MULTIPLY);
8
IntelliJ Amiya

Il existe maintenant un moyen beaucoup plus simple: Android-holo-colors.com

Il vous permettra de changer facilement les couleurs de tous les éléments dessinables holo (boutons, fileuses, ...). Vous sélectionnez la couleur, puis vous téléchargez un fichier Zip contenant des éléments dessinables pour toutes les résolutions.

8
Dalmas

Dans <Button>, utilisez Android:background="#33b5e5". ou mieux Android:background="@color/navig_button"

4
lalitm

Vous pouvez également utiliser cet outil en ligne pour personnaliser votre bouton http://angrytools.com/Android/button/ et utiliser Android:background="@drawable/custom_btn" pour définir le bouton personnalisé dans votre présentation.

3
JRE.exe

La bibliothèque de composants DroidUX possède un widget ColorButton dont la couleur peut être facilement modifiée, à la fois via la définition xml et par programmation au moment de l'exécution, de sorte que vous pouvez même laisser l'utilisateur définir le bouton couleur/thème si votre application le permet.

3
Ricky Lee

Vous pouvez définir le thème de votre bouton à cette

<style name="AppTheme.ButtonBlue" parent="Widget.AppCompat.Button.Colored">
 <item name="colorButtonNormal">@color/HEXColor</item>
 <item name="Android:textColor">@color/HEXColor</item>
</style>
2
Manoj Bhadane

Une méthode simple consiste à définir une classe de boutons personnalisée qui accepte toutes les propriétés souhaitées, telles que le rayon, le dégradé, la couleur pressée, la couleur normale, etc. Un échantillon est ici

Ceci est extrêmement utile si vous avez beaucoup de boutons avec les mêmes propriétés comme le rayon, la couleur sélectionnée, 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 appuyé

enter image description here

1
redDragonzz

Selon les directives de conception du matériau, vous devez utiliser le style ci-dessous, code

<style name="MyButton" parent="Theme.AppCompat.Light>
    <item name="colorControlHighlight">#F36F21</item>
    <item name="colorControlHighlight">#FF8D00</item>
</style>

et dans la mise en page ajouter cette propriété à votre bouton

    Android:theme="@style/MyButton"
0
Shivam

C'est simple .. ajoutez cette dépendance dans votre projet et créez un bouton avec 1. N'importe quelle forme 2. N'importe quelle couleur 3. N'importe quelle bordure 4. Avec des effets importants

https://github.com/manojbhadane/QButton

<com.manojbhadane.QButton
       Android:layout_width="match_parent"
       Android:layout_height="wrap_content"
       Android:text="OK"
       app:qb_backgroundColor="@color/green"
       app:qb_radius="100"
       app:qb_strokeColor="@color/darkGreen"
       app:qb_strokeWidth="5" />
0
Manoj Bhadane

Pour créer un bouton de style différent qui fonctionne assez bien, je sous-classe l'objet Button et applique un filtre de couleur. Cela gère également les états activés et désactivés en appliquant une 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
Matthew Cawley

valeurs\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>

ensuite:

<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
Milan Hlinák