diseño - botones material design android studio
Efecto material sobre botón con color de fondo. (16)
Estoy usando la biblioteca de soporte de Android v21.
He creado un botón con color de fondo personalizado. Los efectos de diseño de Material como ondulación, revelación desaparecen (excepto la elevación al hacer clic) cuando uso el color de fondo.
<Button
style="?android:attr/buttonStyleSmall"
android:background="?attr/colorPrimary"
android:textColor="@color/white"
android:textAllCaps="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button1"
/>
El siguiente es un botón normal y los efectos están funcionando bien.
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAllCaps="true"
android:text="Button1"
/>
Aplicando programáticamente 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
Con AppCompat (22.1.1+) puede agregar un estilo como este:
<style name="MyGreenButton">
<item name="colorButtonNormal">#009900</item>
</style>
Y utilízalo simplemente aplicando el estilo:
<android.support.v7.widget.AppCompatButton
style="@style/MyGreenButton"
android:layout_width="match_width"
android:layout_height="wrap_content"
android:text="A Green Button"
/>
Cambiando el color programáticamente, descubrí que la única forma de actualizar el color (en API 15 o 16) era usar la ''lista de tinte de fondo'' en su lugar. Y no elimina la buena animación radial en los dispositivos API 21:
ColorStateList colorStateList = new ColorStateList(new int[][] {{0}}, new int[] {0xFF009900}); // 0xAARRGGBB
button.setSupportBackgroundTintList(colorStateList);
Debido a que 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.
Cuando usas android:background
, estás reemplazando gran parte del estilo 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 el colorButtonNormal
su tema para el color deshabilitado y colorAccent
para el color habilitado.
Esto le permite aplicarlo a su botón directamente a través de
<Button
...
style="@style/Widget.AppCompat.Button.Colored" />
Si necesita un colorButtonNormal
o colorAccent
, puede usar un ThemeOverlay
como se explica en Widget.AppCompat.Button.Colored y android:theme
en el botón.
Respuesta anterior
Puede usar un dibujo en su directorio v21 para su fondo como:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:drawable="?attr/colorPrimary"/>
</ripple>
Esto asegurará que su color de fondo sea ?attr/colorPrimary
y tenga la animación de ondulación predeterminada usando la ?attr/colorControlHighlight
(que también puede configurar en su tema si lo desea).
Nota: tendrás que crear un selector personalizado por menos de v21:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primaryPressed" android:state_pressed="true"/>
<item android:drawable="@color/primaryFocused" android:state_focused="true"/>
<item android:drawable="@color/primary"/>
</selector>
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 media a través de la selección y saqué el estado primario / enfocado de eso.
Esta es una forma simple y compatible con versiones anteriores de entregar un efecto de onda a los botones elevados con el fondo personalizado.
Tu diseño debería verse así
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/my_custom_background"
android:foreground="?android:attr/selectableItemBackground"/>
Existe otra solución simple para proporcionar un fondo personalizado para los botones "Planos" mientras se mantienen sus efectos "Materiales".
- Coloque su botón en ViewGroup con el fondo deseado establecido allí
- establecer selectableItemBackground desde el tema actual como fondo para su botón (API> = 11)
es decir:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/blue">
<Button
style="?android:attr/buttonStyleSmall"
android:background="?android:attr/selectableItemBackground"
android:textColor="@android:color/white"
android:textAllCaps="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button1"
/>
</FrameLayout>
Se puede usar para botones Flat , funciona en API> = 11, y obtendrá un efecto de rizado en dispositivos> = 21, manteniendo los botones normales en pre-21 hasta que AppCompat se actualice para admitir el rizado allí también.
También puede usar selectableItemBackgroundBorderless para los botones> = 21 solamente.
Hay dos enfoques explicados en el gran tutorial: Alex Lockwood: http://www.androiddesignpatterns.com/2016/08/coloring-buttons-with-themeoverlays-background-tints.html :
Enfoque # 1: Modificar el color de fondo del botón con un ThemeOverlay
<!-- res/values/themes.xml -->
<style name="RedButtonLightTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorAccent">@color/googred500</item>
</style>
<Button
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/RedButtonLightTheme"/>
Enfoque n. ° 2: Configuración del tinte de fondo de AppCompatButton
<!-- res/color/btn_colored_background_tint.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Disabled state. -->
<item android:state_enabled="false"
android:color="?attr/colorButtonNormal"
android:alpha="?android:attr/disabledAlpha"/>
<!-- Enabled state. -->
<item android:color="?attr/colorAccent"/>
</selector>
<android.support.v7.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="@color/btn_colored_background_tint"/>
Intenté esto:
android:backgroundTint:"@color/mycolor"
En lugar de cambiar la propiedad de fondo. Esto no elimina el efecto material.
La respuesta de @ianhanniballake es absolutamente correcta y simple. Pero me tomó unos días entenderlo. Para alguien que no entiende su respuesta, aquí hay una implementación más detallada.
<Button
android:id="@+id/btn"
style="@style/MaterialButton"
... />
<style name="MaterialButton" parent="Widget.AppCompat.Button.Colored">
<item name="android:theme">@style/Theme.MaterialButton</item>
...
</style>
<style name="Theme.MaterialButton" parent="YourTheme">
<item name="colorAccent">@color/yourAccentColor</item>
<item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>
=== O ===
<Button
android:id="@+id/btn"
style="@style/Widget.AppCompat.Button.Colored"
android:theme="@style/Theme.MaterialButton" />
<style name="Theme.MaterialButton" parent="YourTheme">
<item name="colorAccent">@color/yourAccentColor</item>
<item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>
Llegué a esta publicación en busca de una manera de tener un color de fondo de mi artículo de ListView
, pero mantener la onda.
Simplemente agregué mi color como fondo y el selectableItemBackground como primer plano:
<style name="my_list_item">
<item name="android:background">@color/white</item>
<item name="android:foreground">?attr/selectableItemBackground</item>
<item name="android:layout_height">@dimen/my_list_item_height</item>
</style>
Y funciona como un encanto. Supongo que la misma técnica podría usarse también para los botones. Buena suerte :)
Me encontré con este problema hoy jugando con la biblioteca v22.
Suponiendo que está usando estilos, puede establecer la propiedad colorButtonNormal
y los botones usarán ese color de manera predeterminada.
<style name="AppTheme" parent="BaseTheme">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/primaryColor</item>
<item name="colorPrimaryDark">@color/primaryColorDark</item>
<item name="colorAccent">@color/accentColor</item>
<item name="colorButtonNormal">@color/primaryColor</item>
</style>
Aparte de eso, aún podría hacer un estilo para el botón y luego usarlo por botón si necesita una variedad de colores (no ha probado, solo especular).
Recuerde agregar android:
antes de los nombres de los elementos en su estilo v21 .
Si está de acuerdo con el uso de una biblioteca de terceros, consulte 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 de onda 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 repositorio de GitHub de las bibliotecas:
<com.andexert.library.RippleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:rv_centered="true">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@android:drawable/ic_menu_edit"
android:background="@android:color/holo_blue_dark"/>
</com.andexert.library.RippleView>
Puede cambiar el color de la onda agregando este atributo al elemento RippleView: app:rv_color="@color/my_fancy_ripple_color
Si estás interesado en ImageButton puedes probar esto simple:
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_button"
android:background="?attr/selectableItemBackgroundBorderless"
/>
Utilicé el backgroundTint y el primer plano:
<Button
android:layout_width="match_parent"
android:layout_height="40dp"
android:backgroundTint="@color/colorAccent"
android:foreground="?android:attr/selectableItemBackground"
android:textColor="@android:color/white"
android:textSize="10sp"/>
Utilice 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 la barra de herramientas de estilo. Ahora puede usar android: theme para las barras de herramientas en todos los dispositivos de nivel 7 y superior de API y la compatibilidad de android: theme para todos los widgets en dispositivos de nivel 11 y superior de API.
Entonces, en lugar de configurar el color deseado en un tema global, creamos uno nuevo y lo asignamos solo al Button
Ejemplo:
<style name="MyColorButton" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorButtonNormal">@color/myColor</item>
</style>
Y usa este estilo como tema de tu Button
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button1"
android:theme="@style/MyColorButton"/>
<android.support.v7.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="#fff"
android:textColor="#000"
android:text="test"/>
Utilizar
xmlns:app="http://schemas.android.com/apk/res-auto"
Y el color se aceptará en pre-lolipop.