Pregunta

Me gustaría cambiar el color de un botón estándar de Android ligeramente con el fin de adaptarse mejor a la marca de un cliente.

La mejor manera que he encontrado para hacer esto hasta ahora es cambiar dibujable del Button a la dibujable situado en 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>

Pero hacer que requiere que en realidad crear tres dibujables diferentes para cada botón Quiero personalizar (uno para el botón en reposo, uno cuando se enfoca, y uno cuando se pulsa). Eso parece más complicado y no seco de lo que necesito.

Todo lo que realmente quiero hacer es aplicar algún tipo de transformación de color al botón. ¿Existe una manera más fácil de hacer para cambiar de un botón de color de lo que estoy haciendo?

¿Fue útil?

Solución

he descubierto que todo esto puede hacerse en un solo archivo con bastante facilidad. Poner algo como el siguiente código en un archivo llamado custom_button.xml y luego configurar background="@drawable/custom_button" en su opinión botón:

<?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>

Otros consejos

A raíz de la respuesta de Tomasz, también se puede establecer mediante programación la sombra de todo el botón utilizando el modo multiplicar PorterDuff. Esto cambiará el color del botón en lugar de sólo el matiz.

Si usted comienza con un botón con sombra gris estándar:

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

le dará un botón rojo con sombra,

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

le dará un botón a la sombra verde, etc., donde el primer valor es el color en formato hexadecimal.

Su acción consiste en multiplicar el valor del botón de color actual por el valor de color. Estoy seguro de que también hay mucho más que puede hacer con estos modos.

Mike, que podría estar interesado en los filtros de color.

Un ejemplo:

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

Probar para lograr el color que desee.

Esta es mi solución que funciona perfectamente comenzando API 15 . Esta solución mantiene a todos los efectos predeterminadas de los botones de clic, como RippleEffect material. No he probado en las API más bajos, pero debería funcionar.

Todo lo que tiene que hacer, es:

1) Crear un estilo que cambia sólo colorAccent:

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

Te recomiendo usar ThemeOverlay.AppCompat o su AppTheme principal como padre, para mantener el resto de sus estilos.

2) Añadir estas dos líneas a su widget button:

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

A veces, su nueva colorAccent no se muestra en la vista previa de Studio Android, pero cuando se lanza la aplicación en el teléfono, se cambiará el color.


widget de botón de muestra

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

 botón de muestra con el color personalizado

Ahora puede utilizar también de AppCompatButton con el atributo 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"/>

Me gusta la sugerencia de filtro de color en las respuestas anteriores de @conjugatedirection y @Tomasz; Sin embargo, he encontrado que el código proporcionado hasta el momento no se ha aplicado la misma facilidad que lo que esperaba.

En primer lugar, no se menciona en donde para aplicar y limpiar el filtro de color. Es posible que existan otros buenos lugares para hacer esto, pero lo que vino a mi mente fue un OnTouchListener .

A partir de mi lectura de la pregunta original, la solución ideal sería uno que no implique ninguna imagen. La respuesta aceptada utilizando custom_button.xml de @emmby es probablemente un mejor ajuste de los filtros de color, si ese es su objetivo. En mi caso, estoy empezando con una imagen PNG de un diseñador de interfaces de lo que se supone que el botón para que parezca. Si fijo el fondo del botón a esta imagen, las votaciones destacado por defecto se pierde por completo. Este código sustituye al comportamiento con un efecto de oscurecimiento programática.

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();
    }
});

extraje esto como una clase separada para su aplicación a varios botones -. Como muestra la clase interna anónima sólo para obtener la idea

Si usted está haciendo botones de color con XML puede hacer que el código un poco más limpio, especificando el estado de enfoque y se prensa en un archivo separado y reutilizarlos. Mi botón verde se ve así:

<?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 solución más corto que trabaja con cualquier versión de Android:

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

Notas / Requisitos

  • Utilice el espacio de nombres app: y no el espacio de nombres android:!
  • appcompat versión> 24.2.0

    {dependencias     compilar 'com.android.support:appcompat-v7:25.3.1' }

Explicación : introducir descripción de la imagen aquí

Estoy utilizando este enfoque

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>

Como se puede ver desde arriba, estoy usando un estilo personalizado para mi botón. El color del botón se corresponde con el color de acento. Esto me parece un enfoque mucho mejor que el establecimiento android:background como no voy a perder el efecto dominó Google ofrece.

Hay una manera mucho más fácil ahora: android-holo-colors.com

Se le permitirá cambiar los colores de todos los holo dibujables (botones, hiladores, ...) fácilmente. Se selecciona el color y luego descargar un archivo zip que contiene dibujables para todas las resoluciones.

Se usa de esta manera:

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

En <Button> uso android:background="#33b5e5". o mejor android:background="@color/navig_button"

El DroidUX biblioteca de componentes tiene un Widget ColorButton cuyo color puede ser cambiado fácilmente, tanto a través de la definición XML y programación en tiempo de ejecución, por lo que incluso puede dejar al usuario configurar el botón de color / tema de si su aplicación lo permite.

También puede utilizar esta herramienta en línea para personalizar el botón http://angrytools.com/android/button/ y el uso android:background="@drawable/custom_btn" para definir el botón personalizado en su diseño.

Puede establecer tema de su botón para este

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

Una forma fácil es simplemente definir una clase de botón personalizado que acepta todas las propiedades que usted desee como radio, gradiente, el color se pulsa, el color normal etc y luego sólo tiene que utilizar en sus diseños de XML en lugar de establecer el fondo usando XML. Una muestra es aquí

Esto es muy útil si usted tiene una gran cantidad de botones con mismas propiedades como la radio, el color seleccionado, etc Usted puede personalizar el botón heredada de manejar estas propiedades adicionales.

Resultado (No se utilizó ningún selector de fondo).

normal

Imagen normal

botón presionado

introducir descripción de la imagen aquí

La forma en que hago un botón de estilo diferente, que funciona bastante bien es una subclase del objeto Button y aplicar un filtro de color. Este también se encarga de activo e inactivo estados mediante la aplicación de un alfa al botón.

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;
        }
    }

}

Los valores 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>

a continuación:

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

número

Según las directrices de diseño de materiales, es necesario utilizar el estilo como     por debajo de código

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

y en la disposición añadir esta propiedad a su botón

    android:theme="@style/MyButton"

Su simple .. añadir esta dependencia en su proyecto y crear un botón con 1. Cualquier forma 2. Cualquier color 3. Cualquier frontera 4. Con efectos materiales

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" />
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top