Question

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

La meilleure façon que je l'ai trouvé pour ce faire est jusqu'à présent pour changer le drawable du Button au drawable 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 dessinables différentes pour chaque bouton que je veux personnaliser (un pour le bouton au repos, un quand concentré, et un lorsqu'il est pressé). Cela semble plus compliqué et non-DRY que j'ai besoin.

Tout ce que je veux vraiment faire est d'appliquer une sorte de transformation de couleur du bouton. Est-il un moyen plus facile d'aller à changer la couleur d'un bouton que je fais?

Était-ce utile?

La solution

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 puis définissez background="@drawable/custom_button" dans votre vue 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>

Autres conseils

À la suite de la réponse de Tomasz, vous pouvez également définir par programmation l'ombre du bouton entier à l'aide du mode de multiplication PORTERDUFF. Cela va changer la couleur du bouton plutôt que la teinte.

Si vous commencez avec 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 ombragé etc., où la première valeur est la couleur au format hexadécimal.

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

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 souhaitée.

Ceci est ma solution qui fonctionne parfaitement à partir API 15 . Cette solution conserve tous les boutons par défaut des effets de clic, comme RippleEffect matériel. Je ne l'ai pas testé sur les API plus bas, mais il devrait fonctionner.

Tout ce que vous devez faire, 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, de garder 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 nouvelle colorAccent ne montre pas dans Android aperçu Studio, mais quand vous lancez votre application sur le téléphone, la couleur sera modifiée.


widget Bouton échantillon

<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" />

 Bouton d'échantillon avec couleur personnalisée

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

J'aime la suggestion de filtre de couleur dans les réponses précédentes de @conjugatedirection et @Tomasz; Cependant, je trouve que le code fourni à ce jour n'a pas été aussi facile à appliquer comme je m'y attendais.

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

De ma lecture de la question initiale, la solution idéale serait celle qui ne comporte pas d'images. La réponse acceptée à l'aide de custom_button.xml @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 mets à cette image, les évaluations en surbrillance par défaut est complètement perdu l'arrière-plan du bouton. Ce code remplace ce comportement avec un effet assombrissant 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'extrait cela comme une catégorie distincte pour l'application sur plusieurs boutons -. Affichée sous forme de classe interne anonyme juste pour l'idée

Si vous faites des boutons de couleur avec XML, vous pouvez rendre le code un peu plus propre en spécifiant l'état concentré 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>

La solution la plus courte qui fonctionne avec toutes les versions 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 {     compilation « com.android.support:appcompat-v7:25.3.1 » }

Explication : entrer la description d'image ici

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 de la touche correspond à la couleur d'accentuation. Je trouve cela une approche beaucoup mieux que la mise en android:background que je ne perdrai pas l'effet d'entraînement Google fournit.

Il y a une façon beaucoup plus facile maintenant: android-holo-colors.com

Il vous permet de changer les couleurs de tous les holo dessinables (boutons, filateurs, ...) facilement. Vous sélectionnez la couleur, puis télécharger un fichier zip contenant dessinables pour toutes les résolutions.

Utilisez ainsi:

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

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

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

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

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

Un moyen facile est de définir simplement une classe de bouton personnalisé qui accepte toutes les propriétés que vous désirez comme rayon, gradient, couleur pressé, couleur normale, etc., puis il suffit d'utiliser que dans vos mises en page XML au lieu de mettre en place l'arrière-plan à l'aide XML. Un échantillon est

Ceci est extrêmement utile si vous avez beaucoup de boutons ayant les mêmes propriétés comme rayon, etc. couleur sélectionnée Vous pouvez personnaliser votre bouton Héritées pour gérer ces propriétés supplémentaires.

Résultat (pas de sélecteur de base a été utilisé).

normal

Image normale

Pressé

entrer image description ici

La façon dont je fais un autre bouton Styled qui fonctionne très bien est sous-classe l'objet Button et appliquer un filtre de couleur. Ce états gère également activés et désactivés en appliquant un alpha du 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;
        }
    }

}

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>

alors:

<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" />

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

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

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

    android:theme="@style/MyButton"

cont .. ajouter cette dépendance dans votre projet et créer un bouton 1. Toute forme 2. Toute couleur 3. Toute frontière 4. Avec des effets matériels

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" />
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top