minwidth - view en android studio
BackgroundTint de Lollipop no tiene efecto en un botón (14)
Tengo un botón en mi actividad, y me gustaría que tenga el color de acento de mi tema.
En lugar de hacer mis propios dibujos como si tuviéramos que hacer pre-Lollipop, naturalmente me gustaría usar el nuevo atributo
backgroundTint
.
<Button
android:id="@+id/btnAddCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="@color/accent"
android:text="@string/addressInfo_edit_addCode" />
Desafortunadamente no tiene ningún efecto, el botón permanece gris.
Intenté diferentes valores para
backgroundTintMode
, que no cambiaron nada.
También intenté hacerlo programáticamente en mi Actividad, que no cambió nada.
addCodeView.findViewById(R.id.btnAddCode).setBackgroundTintList(
getResources().getColorStateList(R.color.accent));
¿Por qué se ignora mi tinte?
EDITAR: Solo para aclarar, de hecho estoy probando en un dispositivo Lollipop. Otros widgets (por ejemplo, EditText) están teñidos de forma correcta y automática.
Las malas noticias
Como dice BoD, no tiene sentido teñir el fondo de un botón en Lollipop 5.0 (API nivel 21).
Las buenas noticias
Lollipop 5.1 (API nivel 22) parece haber solucionado esto cambiando btn_mtrl_default_shape.xml (entre otros archivos): https://android.googlesource.com/platform/frameworks/base/+/6dfa60f33ca6018959ebff1efde82db7d2aed1e3%5E!/#F0
La gran noticia
La nueva biblioteca de soporte (versión 22.1+) agrega soporte de tinte compatible con versiones anteriores a muchos componentes, incluido AppCompatButton .
Desafortunadamente, la propiedad
android:backgroundTint
todavía no funciona (tal vez estoy haciendo algo mal), por lo que debe configurar
ColorStateList
en el código, usando
setSupportBackgroundTintList()
.
Sería realmente bueno ver
android:backgroundTint
compatible en el futuro.
Actualización
: Marcio Granzotto comentó que la
app:backgroundTint
funciona en AppCompatButton!
Tenga en cuenta que es
app:
no
android:
porque está en la aplicación / biblioteca.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<AppCompatButton
android:id="@+id/mybutton"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Testing, testing"
app:backgroundTint="#ff00ff"/>
</LinearLayout>
Su actividad
AppCompatButton
automáticamente un
AppCompatButton
lugar del
Button
normal si lo deja heredar de
AppCompatActivity
.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AppCompatButton v = (AppCompatButton) findViewById(R.id.mybutton);
ColorStateList csl = new ColorStateList(new int[][]{new int[0]}, new int[]{0xffffcc00});
v.setSupportBackgroundTintList(csl);
}
}
Por supuesto, debería obtener
ColorStateList
de un recurso de color, pero yo era vago, así que ...
Ah, y no olvides basar el tema de tu aplicación en uno de los temas
Theme.AppCompat
, o las vistas de compatibilidad serán muy, muy tristes ...;)
Esto funcionó tanto en 2.3.7 (Gingerbread MR1) como en 5.0 (Lollipop ''Classic'').
Creo que necesitas tener
android:background
configurado para hacer que
android:backgroundTint
funcione.
Para ser más exactos, supongo que no puede
RippleDrawable
un
RippleDrawable
.
RippleDrawable
el
backgroundTint
del botón predeterminado de los temas de Material, que se define como
RippleDrawable
.
No estoy seguro de si esto se recomienda, pero puede intentarlo:
Drawable newDrawable = mBtnAction.getBackground(); // obtain Bg drawable from the button as a new drawable
DrawableCompat.setTint(newDrawable, mActivity.getHomeTobBarBGColor()); //set it''s tint
mBtnAction.setBackground(newDrawable); //apply back to button
En un sentido general funciona.
ViewCompat
pero no parece funcionar correctamente.
Para resolver problemas relacionados con el tinte en Android 5.0.x, uso algo como esto:
public static void setButtonTint(Button button, ColorStateList tint) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP && button instanceof AppCompatButton) {
((AppCompatButton) button).setSupportBackgroundTintList(tint);
} else {
ViewCompat.setBackgroundTintList(button, tint);
}
}
Utiliza el método de soporte solo para API 21 y ViewCompat para todos los demás casos.
Parece que teñir un dibujo ondulado no tiene sentido (y el fondo predeterminado de un botón es un dibujo ondulado).
De hecho, después de mirar el botón predeterminado de la plataforma dibujable, encontré la forma "correcta" de hacer esto: Tienes que definir esto en tu tema:
<item name="android:colorButtonNormal">@color/accent</item>
(Por supuesto, esto es solo para el nivel 21+).
Advertencia: dado que esto se define en un tema, usará el color dado para todos los botones (al menos todos los botones en actividades que usan ese tema).
Como beneficio adicional, también puede cambiar el color de ondulación definiendo esto:
<item name="android:colorControlHighlight">@color/accent_ripple</item>
Porque el atributo
backgroundTint
solo se usa en API nivel 21 y superior
Probado en API 19 a API 27
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.AppCompatButton
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/retry"
android:textColor="@android:color/white"
app:backgroundTint="@android:color/holo_red_dark" />
produce salida como -
Se informó un problema similar en google https://code.google.com/p/android/issues/detail?id=201873
Pero después del lanzamiento de la Biblioteca de soporte de Android, revisión 23.2.1 (marzo de 2016) Este error está resuelto.
Problema: FloatingActionButton.setBackgroundTintList (tinte @Nullable ColorStateList) ya no cambia el color de fondo
actualizar la Biblioteca de soporte a la Biblioteca de soporte de
Android Support Library to 23.2.1
Use la biblioteca de soporte de diseño (23.2.1) y los widgets compactos de aplicaciones como se muestra a continuación
23.2.1 :
AppCompat (también conocido como ActionBarCompat) comenzó como un backport de la API de Android 4.0 ActionBar para dispositivos que se ejecutan en Gingerbread, proporcionando una capa API común en la parte superior de la implementación backportada y la implementación del marco. AppCompat v21 ofrece una API y un conjunto de características que está actualizado con Android 5.0
Biblioteca de soporte de Android 22.1 :
La capacidad de teñir widgets automáticamente cuando se usa AppCompat es increíblemente útil para mantener una marca sólida y coherente en toda la aplicación. Esto se hace automáticamente cuando se inflan los diseños, reemplazando Button con AppCompatButton, TextView con AppCompatTextView, etc. para garantizar que cada uno pueda soportar el tinte. En esta versión, esos widgets con reconocimiento de tinte ahora están disponibles públicamente, lo que le permite mantener el soporte de tinte incluso si necesita subclasificar uno de los widgets compatibles.
Si buscamos en el código fuente de la Biblioteca de soporte, vemos que normalmente teñe los botones conocidos, pero si cambiamos la forma de nuestro botón (tengo un botón redondo), el tinte no funciona bien en api <= 21. También podemos ver que TintManager se convirtió en una clase pública (appcompat-v7: 23.1.1), por lo que podemos tomar ColorStateList de la forma predeterminada del botón (que está teñido bien en 5.0) para el tema actual (por lo que no tenemos que crear la matriz de colores):
Context c = ...; // activity
AppCompatButton ab = ...; // your button
// works ok in 22+:
if (Build.VERSION.SDK_INT <= 21) {
// default appcompat button, that is tinted ok with current theme colors "abc_btn_default_mtrl_shape":
// ColorStateList tint = TintManager.get(c).getTintList(R.drawable.abc_btn_default_mtrl_shape);
// Appcompat 23.2 change:
ColorStateList tint = AppCompatDrawableManager.get().getTintList(c, R.drawable.abc_btn_default_mtrl_shape);
ab.setSupportBackgroundTintList(tint);
}
Simplemente use
app:backgroundTint
lugar de
android:backgroundTint
, el tinte tendrá efecto debajo de Lollipop.
La razón es que
AppCompatActivity
usa
AppCompatViewInflater
para cambiar automáticamente Button o TextView a AppCompatButton o AppCompatTextView, luego la
app:backgroundTint
surte efecto.
Solo usa app: backgroundTint en lugar de android: backgroundTint
Tenga en cuenta que la biblioteca más actualizada de recyclerview puede causar este error también.
Este comando
sendBtnView.setBackgroundTintList(colorState)
funcionó perfectamente en el pasado pero deja de funcionar para mí. después de la investigación resulta que la causa es la lib que se agregó a las dependencias de gradle:
compile ''com.android.support:recyclerview-v7:+''
Así que intenté cambiarlo a 23.02.1 como se recomendó aquí en la publicación de Amit Vaghela. Me cambié a
compile ''com.android.support:recyclerview-v7:23.02.1''
Pero el error de gradle dijo que recyclerview lib no tiene esta versión (23.02.1) (gradle no pudo encontrarla en Jcenter raw.github o repo).
Entonces, porque sabía que el comando setBackgroundTintList solía funcionar bien en el pasado con la versión 22.02.0 ''en todas las otras bibliotecas que tengo en las dependencias de gradle. entonces lo cambio a:
compile ''com.android.support:recyclerview-v7:22.02.0''
Y ahora funciona de nuevo.
puede usar
backgroundTint
<android.support.design.button.MaterialButton
con la versión
"com.android.support:design:28.0.0-rc01"