Pregunta Botón Android estándar con un color diferente


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

La mejor manera que he encontrado para hacer esto hasta ahora es cambiar el ButtonEs dibujable al siguiente dibujante ubicado 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 eso requiere que realmente cree tres estilos diferentes para cada botón que quiera personalizar (uno para el botón en reposo, uno cuando está enfocado y uno cuando lo presiona). 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. ¿Hay una forma más fácil de cambiar el color de un botón que el que estoy haciendo?


688
2017-10-05 18:23


origen


Respuestas:


Descubrí que todo esto se puede hacer en un archivo con bastante facilidad. Pon algo así como el siguiente código en un archivo llamado custom_button.xml y luego establecer background="@drawable/custom_button" en su vista de 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>

694
2017-11-13 00:19



Siguiendo con la respuesta de Tomasz, también puedes establecer programáticamente el tono de todo el botón usando el modo de multiplicar PorterDuff. Esto cambiará el color del botón en lugar de solo el tinte.

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

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

le dará un botón sombreado rojo,

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

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

Funciona al multiplicar el valor del color del botón actual por el valor del color. Estoy seguro de que también hay mucho más que puedes hacer con estos modos.


297
2017-08-15 01:35



Mike, es posible que te interesen los filtros de color.

Un ejemplo:

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

intente esto para lograr el color que desea.


144
2017-08-09 23:28



Esta es mi solución que funciona perfectamente comenzando de la API 15. Esta solución mantiene todos los efectos predeterminados de clic de botón, como material RippleEffect. No lo he probado en API más bajas, pero debería funcionar.

Todo lo que necesitas hacer es:

1) Crea un estilo que solo cambie colorAccent:

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

Recomiendo usar ThemeOverlay.AppCompat o tu principal AppTheme como padre, para mantener el resto de sus estilos.

2) Agregue estas dos líneas a su button widget:

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

A veces tu nuevo colorAccent no se muestra en Android Studio Preview, pero cuando inicie su aplicación en el teléfono, el color cambiará.


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

Sample Button with custom color


71
2017-07-19 20:42



Ahora también puedes usar appcompat-v7's AppCompatButton con el backgroundTint atributo:

<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



Me gusta la sugerencia de filtro de color en respuestas anteriores de @conjugatedirection y @Tomasz; Sin embargo, descubrí que el código proporcionado hasta ahora no se aplicaba tan fácilmente como esperaba.

Primero, no fue mencionado dónde para aplicar y borrar el filtro de color. Es posible que haya otros buenos lugares para hacer esto, pero lo que me vino a la mente fue una OnTouchListener.

A partir de mi lectura de la pregunta original, la solución ideal sería aquella que no implique ninguna imagen. La respuesta aceptada usando custom_button.xml de @emmby es probablemente una mejor opción que los filtros de color si ese es su objetivo. En mi caso, estoy empezando con una imagen png de un diseñador de UI de cómo se supone que debe verse el botón. Si configuro el fondo del botón para esta imagen, la retroalimentación de resaltado predeterminada se pierde por completo. Este código reemplaza ese comportamiento con un efecto de oscurecimiento programático.

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 la aplicación a varios botones, que se muestra como clase interna anónima solo para obtener la idea.


22
2018-06-17 10:56



Si está haciendo botones de color con XML, puede hacer que el código sea un poco más limpio al especificar el estado enfocado y presionado en un archivo separado y volver a utilizarlos. 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>

16
2017-12-16 11:23



La solución más corta que funciona con cualquier versión de Android:

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

Notas / Requisitos:

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

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

Explicación: enter image description here


10
2018-05-04 12:21



Estoy usando 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 puede ver desde arriba, estoy usando un estilo personalizado para mi botón. El color del botón corresponde al color de acento. Encuentro que este es un enfoque mucho mejor que la configuración android:background ya que no perderé el efecto dominó que ofrece Google.


9
2017-11-05 13:23