Efecto material en el botón con el color de fondo

Estoy usando la biblioteca de soporte Android v21.

Creé un botón con un color de fondo personalizado. Los efectos de diseño del material como ondulación, revelar se han ido (excepto la elevación al hacer clic) cuando uso el color de fondo.

Fondo El siguiente es un botón normal y los efectos funcionan bien.

 

Botón predeterminado

Cuando utilizas android:background , estás reemplazando gran parte del diseño y la apariencia de un botón con un color en blanco.

Actualización: a partir de la versión 23.0.0 de AppCompat , hay un nuevo estilo Widget.AppCompat.Button.Colored que utiliza colorButtonNormal su tema para el color desactivado y colorAccent para el color habilitado.

Esto le permite aplicarlo a su botón directamente a través de

  

Si necesita un colorButtonNormal personalizado o colorAccent , puede usar un ThemeOverlay como se explica en este consejo y android:theme en el botón.

Respuesta anterior

Puede usar un dibujo en su directorio v21 para su fondo, como por ejemplo:

     

Esto asegurará que el color de fondo sea ?attr/colorPrimary y tenga la animación de rizado predeterminada utilizando el valor predeterminado ?attr/colorControlHighlight (que también puede establecer en su tema si lo desea).

Nota: deberá crear un selector personalizado por menos de v21:

       

Suponiendo que tiene algunos colores que le gustaría para el estado predeterminado, presionado y enfocado. Personalmente, tomé una captura de pantalla de una onda en el medio de la selección y saqué el estado primario / enfocado de eso.

Hay otra solución simple para proporcionar un fondo personalizado para los botones “Planos” mientras se mantienen sus efectos “Materiales”.

  1. Coloque su botón en ViewGroup con el fondo deseado configurado allí
  2. establecer seleccionableItemBackground del tema actual como fondo para su botón (API> = 11)

es decir:

    

Se puede usar para botones planos , funciona en API> = 11, y obtendrá efecto de ondulación en dispositivos> = 21, manteniendo los botones regulares en pre-21 hasta que AppCompat se actualice para admitir la ondulación allí también.

También puede usar selecttableItemBackgroundBorderless para> = 21 botones solamente.

Aquí hay una forma sencilla y retrocompatible de ofrecer un efecto dominó a los botones elevados con el fondo personalizado.

Tu diseño debería verse así

  

Me encontré con este problema hoy en realidad jugando con la biblioteca v22.

Suponiendo que esté utilizando estilos, puede establecer la propiedad colorButtonNormal y los botones usarán ese color de manera predeterminada.

  

Aparte de eso, aún puedes hacer un estilo para el botón y luego usarlo por botón si necesitas una variedad de colores (no lo has probado, solo especulando).

Recuerde agregar android: antes de los nombres de los elementos en su estilo v21 .

Con AppCompat (22.1.1+) puede agregar un estilo como este:

  

Y úsalo simplemente aplicando el estilo:

  

Al cambiar el color de forma progtwigda, descubrí que la única forma de actualizar el color (en la API 15 o 16) era utilizar la “lista de matices de fondo”. Y no elimina la agradable animación radial en dispositivos API 21:

 ColorStateList colorStateList = new ColorStateList(new int[][] {{0}}, new int[] {0xFF009900}); // 0xAARRGGBB button.setSupportBackgroundTintList(colorStateList); 

Porque button.setBackground(...) y button.getBackground().mutate().setColorFilter(...) no cambian el color del botón en API 15 y 16 como lo hacen en API 21.

La respuesta de @ianhaniballe es absolutamente correcta y simple. Pero me llevó unos días entenderlo. Para alguien que no entiende su respuesta, aquí hay más implementación detallada

    

=== O ===

   

Usé backgroundTint y primer plano:

  

Use backgroundTint lugar de background

v22.1 de appcompat-v7 introdujo algunas nuevas posibilidades. Ahora es posible asignar un tema específico solo a una vista.

Uso obsoleto de la aplicación: tema para diseñar la barra de herramientas. Ahora puede usar android: theme para barras de herramientas en todos los niveles de API 7 y dispositivos superiores y android: compatibilidad con temas para todos los widgets en API de nivel 11 y dispositivos superiores.

Entonces, en lugar de establecer el color deseado en un tema global, creamos uno nuevo y lo asignamos solo al Button

Ejemplo:

  

Y usa este estilo como tema de tu Button

  

Llegué a esta publicación buscando una forma de tener un color de fondo de mi elemento ListView , pero mantengo la onda.

Simplemente agregué mi color como fondo y seleccionableItemBackground como primer plano:

  

Y funciona como un encanto. Supongo que la misma técnica podría usarse también para botones. Buena suerte 🙂

Si está interesado en ImageButton puede intentar esto simple:

  

Si estás de acuerdo con el uso de una biblioteca de terceros, echa un vistazo a traex / RippleEffect . Le permite agregar un efecto Ripple a CUALQUIER vista con solo unas pocas líneas de código. Solo necesita envolver, en su archivo de diseño xml, el elemento que desea que tenga un efecto com.andexert.library.RippleView con un contenedor com.andexert.library.RippleView .

Como beneficio adicional, requiere Min SDK 9 para que pueda tener consistencia de diseño en todas las versiones del sistema operativo.

Aquí hay un ejemplo tomado del repository de GitHub de las bibliotecas:

    

Puede cambiar el color de ondulación agregando este atributo al elemento RippleView: app:rv_color="@color/my_fancy_ripple_color

  

Utilizar

 xmlns:app="http://schemas.android.com/apk/res-auto" 

y el color lo aceptó en pre-lolipop

Hay dos enfoques explicados en el gran tutorial: Alex Lockwood: http://www.androiddesignpatterns.com/2016/08/coloring-buttons-with-themeoverlays-background-tints.html :

Método n. ° 1: modificación del color de fondo del botón w / a ThemeOverlay

   

  

Enfoque n.º 2: configuración del tono de fondo de AppCompatButton

        

  

Aplicación programática de los colores:

 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { ColorStateList colorStateListRipple = new ColorStateList( new int[][] {{0}}, new int[] {Color.WHITE} // ripple color ); RippleDrawable rippleDrawable = (RippleDrawable) myButton.getBackground(); rippleDrawable.setColor(colorStateListRipple); myButton.setBackground(rippleDrawable); // applying the ripple color } ColorStateList colorStateList = new ColorStateList( new int[][]{ new int[]{android.R.attr.state_pressed}, // when pressed new int[]{android.R.attr.state_enabled}, // normal state color new int[]{} // normal state color }, new int[]{ Color.CYAN, // when pressed Color.RED, // normal state color Color.RED // normal state color } ); ViewCompat.setBackgroundTintList(myButton, colorStateList); // applying the state colors 

Intenté esto:

 android:backgroundTint:"@color/mycolor" 

en lugar de cambiar la propiedad de fondo. Esto no elimina el efecto material.