studio - Botones para colorear en Android con Material Design y AppCompat
round button material design (25)
Editar (22.06.2016):
La biblioteca de Appcompat comenzó a admitir botones de material después de que publiqué la respuesta original. En esta publicación puedes ver la implementación más fácil de los botones elevados y planos.
Respuesta original:
Dado que AppCompat no admite el botón, puedes usar xml como fondos. Para hacerlo, eché un vistazo al código fuente de Android y encontré los archivos relacionados para los botones de material de estilo.
1 - Observe la implementación original del botón de material desde la fuente.
Eche un vistazo al btn_default_material.xml en el código fuente de Android .
Puede copiar el archivo en la carpeta drawable-v21 de su proyecto. Pero no toques el color aquí. El archivo que necesita cambiar es el segundo archivo.
drawable-v21 / custom_btn.xml
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>
2 - Obtener la forma del botón material original
Como te das cuenta, hay una forma usada dentro de este dibujo que puedes encontrar en este archivo del código fuente .
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/button_inset_horizontal_material"
android:insetTop="@dimen/button_inset_vertical_material"
android:insetRight="@dimen/button_inset_horizontal_material"
android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
<corners android:radius="@dimen/control_corner_material" />
<solid android:color="?attr/colorButtonNormal" />
<padding android:left="@dimen/button_padding_horizontal_material"
android:top="@dimen/button_padding_vertical_material"
android:right="@dimen/button_padding_horizontal_material"
android:bottom="@dimen/button_padding_vertical_material" />
</shape>
3 - Obtención de dimensiones del botón de material.
Y en este archivo hay algunas dimensiones utilizadas desde el archivo que puede encontrar aquí . Puedes copiar todo el archivo y ponerlo en tu carpeta de valores . Esto es importante para aplicar el mismo tamaño (que se usa en los botones de material) a todos los botones
4 - Crear otro archivo dibujable para versiones antiguas
Para versiones anteriores debes tener otro dibujable con el mismo nombre. Estoy poniendo directamente los artículos en línea en lugar de hacer referencia. Es posible que desee hacer referencia a ellos. Pero nuevamente, lo más importante son las dimensiones originales del botón de material.
drawable / custom_btn.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed state -->
<item android:state_pressed="true">
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/button_inset_horizontal_material"
android:insetTop="@dimen/button_inset_vertical_material"
android:insetRight="@dimen/button_inset_horizontal_material"
android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
<corners android:radius="@dimen/control_corner_material" />
<solid android:color="@color/PRESSED_STATE_COLOR" />
<padding android:left="@dimen/button_padding_horizontal_material"
android:top="@dimen/button_padding_vertical_material"
android:right="@dimen/button_padding_horizontal_material"
android:bottom="@dimen/button_padding_vertical_material" />
</shape>
</inset>
</item>
<!-- focused state -->
<item android:state_focused="true">
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/button_inset_horizontal_material"
android:insetTop="@dimen/button_inset_vertical_material"
android:insetRight="@dimen/button_inset_horizontal_material"
android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
<corners android:radius="@dimen/control_corner_material" />
<solid android:color="@color/FOCUSED_STATE_COLOR" />
<padding android:left="@dimen/button_padding_horizontal_material"
android:top="@dimen/button_padding_vertical_material"
android:right="@dimen/button_padding_horizontal_material"
android:bottom="@dimen/button_padding_vertical_material" />
</shape>
</inset>
</item>
<!-- normal state -->
<item>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/button_inset_horizontal_material"
android:insetTop="@dimen/button_inset_vertical_material"
android:insetRight="@dimen/button_inset_horizontal_material"
android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
<corners android:radius="@dimen/control_corner_material" />
<solid android:color="@color/NORMAL_STATE_COLOR" />
<padding android:left="@dimen/button_padding_horizontal_material"
android:top="@dimen/button_padding_vertical_material"
android:right="@dimen/button_padding_horizontal_material"
android:bottom="@dimen/button_padding_vertical_material" />
</shape>
</inset>
</item>
</selector>
Resultado
Tu botón tendrá un efecto de onda en los dispositivos Lollipop. Las versiones anteriores tendrán exactamente el mismo botón, excepto el efecto de onda. Pero dado que proporciona elementos dibujables para diferentes estados, también responderán a los eventos táctiles (como se hacía antes).
Antes de que AppCompat
actualización de AppCompat
hoy, pude cambiar el color de los botones en Android L pero no en versiones anteriores. Después de incluir la nueva actualización de AppCompat, no puedo cambiar el color de ninguna de las versiones. Cuando intento, el botón simplemente desaparece. ¿Alguien sabe cómo cambiar el color del botón?
Las siguientes imágenes muestran lo que quiero lograr:
El botón blanco es el predeterminado, el rojo es lo que quiero.
Esto es lo que estaba haciendo anteriormente para cambiar el color de los botones en styles.xml
:
<item name="android:colorButtonNormal">insert color here</item>
y hacerlo dinámicamente:
button.getBackground().setColorFilter(getResources().getColor(insert color here), PorterDuff.Mode.MULTIPLY);
También @android:style/Theme.Material.Light.DarkActionBar
el tema principal de @android:style/Theme.Material.Light.DarkActionBar
a Theme.AppCompat.Light.DarkActionBar
ACTUALIZAR
Utilice la biblioteca de soporte de diseño (23.2.0) y los widgets de aplicaciones como se muestra a continuación
En la biblioteca de soporte de Android 22.1 :
Esto se hace automáticamente cuando se inflan diseños, reemplazando Button con AppCompatButton, TextView con AppCompatTextView, etc. para asegurar que cada uno pueda admitir el tintado. En esta versión, los widgets que detectan tinte ahora están disponibles públicamente, lo que le permite mantener el soporte de tintado incluso si necesita subclasificar uno de los widgets compatibles.
La lista completa de widgets para tint:
AppCompatAutoCompleteTextView
AppCompatButton
AppCompatCheckBox
AppCompatCheckedTextView
AppCompatEditText
AppCompatMultiAutoCompleteTextView
AppCompatRadioButton
AppCompatRatingBar
AppCompatSpinner
AppCompatTextView
Diseño de materiales para dispositivos Pre-Lollipop :
AppCompat (también conocido como ActionBarCompat) comenzó como un backport de la API ActionBar de Android 4.0 para dispositivos que se ejecutan en Gingerbread, proporcionando una capa de API común sobre la implementación de backported y la implementación del marco. AppCompat v21 ofrece una API y un conjunto de funciones actualizadas con Android 5.0
Acabo de crear una biblioteca de Android, que te permite modificar fácilmente el color del botón y el color de la onda.
https://github.com/xgc1986/RippleButton
<com.xgc1986.ripplebutton.widget.RippleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn"
android:text="Android button modified in layout"
android:textColor="@android:color/white"
app:buttonColor="@android:color/black"
app:rippleColor="@android:color/white"/>
No es necesario crear un estilo para cada botón que desee con un color diferente, lo que le permite personalizar los colores al azar
Con la última biblioteca de soporte, podría simplemente heredar su actividad de AppCompatActivity
, por lo que AppCompatButton
su Button
como AppCompatButton
y le dará la oportunidad de AppCompatButton
color de cada botón del diseño con el uso de android:theme="@style/SomeButtonStyle"
, donde SomeButtonStyle
es:
<style name="SomeButtonStyle" parent="@android:style/Widget.Button">
<item name="colorButtonNormal">@color/example_color</item>
</style>
Trabajó para mí en 2.3.7, 4.4.1, 5.0.2
Configuré android:textColor
a @null
en el tema de mi botón y ayuda.
styles.xml
<style name="Button.Base.Borderless" parent="Widget.AppCompat.Button.Borderless.Colored">
<item name="android:textColor">@null</item>
</style>
some_layout.xml
<Button
style="@style/Button.Base.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hint" />
Ahora el color del texto del botón es colorAccent
definido en AppTheme
<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="colorAccent">@color/colorAccent</item>
<item name="borderlessButtonStyle">@style/Button.Base.Borderless</item>
<item name="alertDialogTheme">@style/AlertDialog</item>
</style>
Después de 2 días buscando respuestas, la temática de los botones no me funcionó en la API <21.
Mi única solución es anular el tintado de AppCompatButton no solo con el tema base de la aplicación "colorButtonNormal" sino también con la vista backgroundTint como esta:
public class AppCompatColorButton extends AppCompatButton {
public AppCompatColorButton(Context context) {
this(context, null);
}
public AppCompatColorButton(Context context, AttributeSet attrs) {
this(context, attrs, android.support.v7.appcompat.R.attr.buttonStyle);
}
public AppCompatColorButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (TintManager.SHOULD_BE_USED) {
setSupportBackgroundTintList(createButtonColorStateList(getContext(), attrs, defStyleAttr));
}
}
static final int[] DISABLED_STATE_SET = new int[]{-android.R.attr.state_enabled};
static final int[] FOCUSED_STATE_SET = new int[]{android.R.attr.state_focused};
static final int[] PRESSED_STATE_SET = new int[]{android.R.attr.state_pressed};
static final int[] EMPTY_STATE_SET = new int[0];
private ColorStateList createButtonColorStateList(Context context, AttributeSet attrs, int defStyleAttr) {
final int[][] states = new int[4][];
final int[] colors = new int[4];
int i = 0;
final int themeColorButtonNormal = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
/*TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.backgroundTint }, defStyleAttr, 0);
final int colorButtonNormal = a.getColor(0, themeColorButtonNormal);*/
TypedArray a = context.obtainStyledAttributes(attrs, android.support.v7.appcompat.R.styleable.View, defStyleAttr, 0);
final int colorButtonNormal = a.getColor(android.support.v7.appcompat.R.styleable.View_backgroundTint, themeColorButtonNormal);
a.recycle();
final int colorControlHighlight = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorControlHighlight);
// Disabled state
states[i] = DISABLED_STATE_SET;
colors[i] = ThemeUtils.getDisabledThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
i++;
states[i] = PRESSED_STATE_SET;
colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
i++;
states[i] = FOCUSED_STATE_SET;
colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
i++;
// Default enabled state
states[i] = EMPTY_STATE_SET;
colors[i] = colorButtonNormal;
i++;
return new ColorStateList(states, colors);
}
}
A continuación, puede definir el color de su botón de esta manera:
<com.example.views.AppCompatColorButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#ffff0000"
app:backgroundTint="#ffff0000"
android:text="Button"
android:textColor="@android:color/white" />
En la biblioteca de soporte de Android 22.1.0, Google activó el tono del Button
. Por lo tanto, otra forma de personalizar el color de fondo del botón es usar el atributo backgroundTint
.
Por ejemplo,
<Button
android:id="@+id/add_remove_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/bg_remove_btn_default"
android:textColor="@android:color/white"
tools:text="Remove" />
En realidad no quería un cambio en mis estilos de botones personalizados, pero lamentablemente ya no funcionaban.
Mi aplicación tiene un minSdkVersion de 9 y todo funcionó antes.
No sé por qué, pero desde que quité el android: antes del estilo de botón parece funcionar de nuevo
ahora = trabajando:
<item name="buttonStyle">@style/ButtonmyTime</item>
antes = solo botones de material gris:
<item name="android:buttonStyle">@style/ButtonmyTime</item>
No tengo una carpeta especial para la nueva versión de Android ya que mis botones son bastante planos y deberían tener el mismo aspecto en todas las versiones de Android.
Tal vez alguien pueda decirme por qué tuve que eliminar "android:" El botón de imagen todavía funciona con "android:"
<item name="android:imageButtonStyle">@style/ImageButtonmyTimeGreen</item>
Esta respuesta SO me ayudó a llegar a una respuesta https://.com/a/30277424/3075340
Utilizo este método de utilidad para establecer el tinte de fondo de un botón. Funciona con dispositivos pre-lollipop:
// Set button background tint programmatically so it is compatible with pre-lollipop devices.
public static void setButtonBackgroundTintAppCompat(Button button, ColorStateList colorStateList){
Drawable d = button.getBackground();
if (button instanceof AppCompatButton) {
// appcompat button replaces tint of its drawable background
((AppCompatButton)button).setSupportBackgroundTintList(colorStateList);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Lollipop button replaces tint of its drawable background
// however it is not equal to d.setTintList(c)
button.setBackgroundTintList(colorStateList);
} else {
// this should only happen if
// * manually creating a Button instead of AppCompatButton
// * LayoutInflater did not translate a Button to AppCompatButton
d = DrawableCompat.wrap(d);
DrawableCompat.setTintList(d, colorStateList);
button.setBackgroundDrawable(d);
}
}
Cómo utilizar en el código:
Utility.setButtonBackgroundTintAppCompat(myButton,
ContextCompat.getColorStateList(mContext, R.color.your_custom_color));
De esta manera, no tiene que especificar una ColorStateList si solo desea cambiar el tinte de fondo y nada más, pero mantenga los bonitos efectos de los botones y qué no.
Esto se ha mejorado en v23.0.0 de la biblioteca AppCompat con la adición de más temas, incluyendo
Widget.AppCompat.Button.Colored
En primer lugar, incluya la dependencia appCompat si aún no lo ha hecho.
compile(''com.android.support:appcompat-v7:23.0.0'') {
exclude group: ''com.google.android'', module: ''support-v4''
}
ahora, ya que necesita usar v23 de la aplicación compatible, ¡también deberá apuntar al SDK-v23!
compileSdkVersion = 23
targetSdkVersion = 23
En tus values/theme
<item name="android:buttonStyle">@style/BrandButtonStyle</item>
En tus values/style
<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">@color/yourButtonColor</item>
<item name="android:textColor">@color/White</item>
</style>
En tus values-v21/style
<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
<item name="android:colorButtonNormal">@color/yourButtonColor</item>
<item name="android:textColor">@color/White</item>
</style>
Ya que el tema de tu botón se basa en Widget.AppCompat.Button.Colored
El color del texto en el botón es por defecto blanco!
pero parece que hay un problema cuando desactivas el botón, el botón cambiará su color a gris claro, ¡pero el color del texto seguirá siendo blanco!
Una solución para esto es establecer específicamente el color del texto en el botón a blanco. Como he hecho en el estilo que se muestra arriba.
ahora simplemente puede definir su botón y dejar que AppCompat haga el resto :)
<Button
android:layout_width="200dp"
android:layout_height="48dp" />
Fijado oficialmente en Support Library rev.22 (viernes, 13 de marzo de 2015). Ver problema relevante del código de Google:
https://issuetracker.google.com/issues/37008632
Ejemplo de uso
theme.xml:
<item name="colorButtonNormal">@color/button_color</item>
v21 / theme.xml
<item name="android:colorButtonNormal">@color/button_color</item>
La respuesta está en TEMA no estilo.
El problema es que el color del botón se adhiere al colorButtonNormal del tema. He intentado cambiar el estilo de muchas maneras diferentes sin suerte. Así que cambié el tema del botón .
Crea un tema con colorButtonNormal y colorPrimary:
<style name="ThemeAwesomeButtonColor" parent="AppTheme">
<item name="colorPrimary">@color/awesomePrimaryColor</item>
<item name="colorButtonNormal">@color/awesomeButtonColor</item>
</style>
Usa este tema en el botón
<Button
android:id="@+id/btn_awesome"
style="@style/AppTheme.Button"
android:theme="@style/ThemeAwesomeButtonColor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/btn_awesome"/>
El "AppTheme.Button" puede ser cualquier cosa que amplíe el estilo del botón, como aquí, uso el color primario para el color del texto:
<style name="AppTheme.Button" parent="Base.Widget.AppCompat.Button">
...
<item name="android:textColor">?attr/colorPrimary</item>
...
</style>
Y obtienes el botón en cualquier color que desees que sea compatible con el diseño del material.
Otra solución simple usando el AppCompatButton
<android.support.v7.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.Button.Colored"
app:backgroundTint="@color/red"
android:text="UNINSTALL" />
Para admitir botones de colores, use la última biblioteca de AppCompat (> 23.2.1 ) con:
inflar - XML
Widget de AppCompat:
android.support.v7.widget.AppCompatButton
Estilo AppCompat:
style="@style/Widget.AppCompat.Button.Colored"
¡NÓTESE BIEN! Para establecer un color personalizado en xml: use la app
attr: en lugar de android
(use alt+enter
o declare xmlns:app="http://schemas.android.com/apk/res-auto"
para usar la app
)
app : backgroundTint = "@ color / your_custom_color"
Ejemplo:
<android.support.v7.widget.AppCompatButton
style="@style/Widget.AppCompat.Button.Colored"
app:backgroundTint="@color/your_custom_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Colored Button"/>
o configurarlo programáticamente - JAVA
ViewCompat.setBackgroundTintList(your_colored_button,
ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));
Para aquellos que usan un ImageButton
aquí es cómo lo haces:
En style.xml:
<style name="BlueImageButton" parent="Base.Widget.AppCompat.ImageButton">
<item name="colorButtonNormal">@color/primary</item>
<item name="android:tint">@color/white</item>
</style>
en v21 / style.xml:
<style name="BlueImageButton" parent="Widget.AppCompat.ImageButton">
<item name="android:colorButtonNormal">@color/primary</item>
<item name="android:tint">@color/white</item>
</style>
Luego en su archivo de diseño:
<android.support.v7.widget.AppCompatImageButton
android:id="@+id/my_button"
android:theme="@style/BlueImageButton"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_check_black_24dp"
/>
Para cambiar el color de un solo botón
ViewCompat.setBackgroundTintList(button, getResources().getColorStateList(R.color.colorId));
Para mí, el problema era que en Android 5.0, android:colorButtonNormal
no tenía ningún efecto, y en realidad, ningún elemento del tema (como android:colorAccent
), pero en Android 4.4.3, por ejemplo, sí. El proyecto se configuró con compileSdkVersion
y targetSdkVersion
a 22, por lo que hice todos los cambios como @Muhammad Alfaifi Sugessted, pero al final, noté que el problema era buildToolsVersion , que no estaba actualizado. Una vez que cambié a 23.0.1 , todo comenzó a funcionar casi como normal. Ahora, android:colorButtonNormal
todavía no tiene ningún efecto, pero al menos el botón reacciona a android:colorAccent
, que para mí es aceptable.
Espero que esta pista pueda ayudar a alguien. Nota: He aplicado el estilo directamente al botón, ya que el botón android:theme=[...]
tampoco tuvo efecto.
Si desea usar el estilo AppCompat como Widget.AppCompat.Button , Base.Widget.AppCompat.Button.Colored , etc., debe usar estos estilos con vistas compatibles de la biblioteca de soporte.
El código a continuación no funciona para dispositivos pre-lolipop:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.Button" />
Necesitas usar AppCompatButton para habilitar los estilos de AppCompat:
<android.support.v7.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.Button" />
Si solo desea el botón de material "Plano", puede personalizar su fondo utilizando el atributo selectableItemBackground como se explica here .
Si utiliza la solución de estilo con colorButtonNormal , no olvide heredar de Widget.AppCompat.Button.Colored para que el efecto de rizado funcione;)
Me gusta
<style name="CustomButtonStyle" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">@android:color/white</item>
</style>
Una forma de llevar esto a cabo le permite simplemente señalar un estilo y NO tema todos los botones en su aplicación de la misma manera.
En themes.xml agregar un tema
<style name="Theme.MyApp.Button.Primary.Blue" parent="Widget.AppCompat.Button">
<item name="colorButtonNormal">@color/someColor</item>
<item name="android:textColorPrimary">@android:color/white</item>
</style>
Ahora en styles.xml agregar
<style name="MyApp.Button.Primary.Blue" parent="">
<item name="android:theme">@style/Theme.MyApp.Button.Primary.Blue</item>
</style>
Ahora en su diseño simplemente señale el ESTILO en su Botón
<Button
...
style="@style/MyApp.Button.Primary.Blue"
... />
Yo uso esto. Efecto de ondulación y botón de clic de sombra de trabajo.
style.xml
<style name="Button.Red" parent="Widget.AppCompat.Button.Colored">
<item name="android:textColor">@color/material_white</item>
<item name="android:backgroundTint">@color/red</item>
</style>
Botón en el diseño:
<Button
style="@style/Button.Red"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/close"/>
esto me funciona con appcompat-v7: 22.2.0 en Android + 4.0
en tu styles.xml
<style name="Button.Tinted" parent="Widget.AppCompat.Button">
<item name="colorButtonNormal">YOUR_TINT_COLOR</item>
<item name="colorControlHighlight">@color/colorAccent</item>
<item name="android:textColor">@android:color/white</item>
</style>
en su archivo de diseño
<Button
android:id="@+id/but_next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/but_continue"
android:theme="@style/Button.Tinted" />
Diseño:
<android.support.v7.widget.AppCompatButton
style="@style/MyButton"
...
/>
styles.xml:
<style name="MyButton" parent="Widget.AppCompat.Button.Colored">
<item name="backgroundTint">@color/button_background_selector</item>
<item name="android:textColor">@color/button_text_selector</item>
</style>
color / button_background_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#555555"/>
<item android:color="#00ff00"/>
</selector>
color / button_text_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#888888"/>
<item android:color="#ffffff"/>
</selector>