vectordrawables - vector xmlns android
Selector de Android extraíble con VectorDrawables srcCompat (4)
Algunas cosas han cambiado desde que hice esta pregunta, así que la responderé yo mismo.
Con Support Library 23.4.0 se volvió a habilitar el soporte para VectorDrawables de Ressources: Android Support Library 23.4.0 disponible ahora
Puede encontrar más información al respecto en este reparto de Google I / O 2016: Novedades en la biblioteca de soporte - Google I / O 2016
Debe agregar esto a cada Actividad en la que desee usar VectorDrawables en dispositivos con Android 5.0 (Codename Lollipop, API nivel 21):
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Por lo tanto, ahora puede usar VectorDrawables en DrawableContainers pero aún puede causar algunos problemas como se menciona en las fuentes anteriores, así que úselo con precaución.
Hasta ahora no volví a habilitar esta función en mi aplicación, pero cambiaré muchos de mis íconos a VectorDrawables con mi próximo lanzamiento principal y luego profundizaré en este tema.
Estoy enfrentando un problema con la nueva compatibilidad con VectorDrawables. En la Biblioteca de soporte 23.2 había una nueva característica para la compatibilidad con versiones anteriores de Android VectorDrawables.
Tengo un ImageView que es un SelectorDrawable asignado. Este Drawable contiene varios VectorDrawables, así que pensé que debería usar la aplicación: srcCompat por compatibilidad. Pero no funciona en mi Galaxy S2 con Android 4.1.2.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_gps_fixed_24dp"android:state_activated="true" android:state_selected="true"></item>
<item android:drawable="@drawable/ic_gps_not_fixed_24dp" android:state_activated="true" android:state_selected="false"></item>
<item android:drawable="@drawable/ic_gps_not_fixed_24dp" android:state_activated="false" android:state_selected="true"></item>
<item android:drawable="@drawable/ic_gps_off_24dp" android:state_activated="false" android:state_selected="false"></item>
<item android:drawable="@drawable/ic_gps_not_fixed_24dp"></item>
</selector>
Todos los elementos dibujables son archivos vectoriales xml.
Cuando uso este SelectorDrawable con srcCompat me sale este error:
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ic_gps_fixed_24dp.xml from drawable resource ID #0x7f0201c1
at android.content.res.Resources.loadDrawable(Resources.java:1951)
at android.content.res.Resources.getDrawable(Resources.java:672)
at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:173)
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:881).xml from drawable resource ID #0x7f0201c1
usando android: src es aún peor.
Si uso uno de los vectores dibujables con la aplicación: srcCompat todo funciona bien. Así que supongo que es un problema con el SelectorDrawable y la compatibilidad.
¿Alguien ha tenido el mismo problema y ha encontrado una solución o actualmente no es posible usar VectorDrawables en SelectorDrawables antes de Android 5?
Los hechos rápidos:
- Compilar Target API 23
- Soporte Libraray 23.3.0
- vectorDrawables.useSupportLibrary = true
- Gradle 2.0
Como @Jahnold mencionó en el comentario a la pregunta, el soporte para cargar vectores dibujables desde una lista xml de estado xml se eliminó en 23.3.
Sin embargo, encontré varios enfoques que pueden ayudar.
1. Usando Tinte
El enfoque es adecuado si los elementos dibujables del estado seleccionado se diferencian solo por colores.
Primero, cree un solo vector dibujable con tinte y
fillColor
color
fillColor
:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tintMode="multiply"
android:tint="@color/button_tint">
<path
android:fillColor="#ffffff"
android:pathData="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
<path
android:pathData="M0 0h24v24H0z"/>
</vector>
En segundo lugar, cree la lista de estado de color
button_tint.xml
colocado en
res/color
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#555555" android:state_enabled="false"/>
<item android:color="#6699dd"/>
</selector>
No olvide agregar líneas de seguimiento a
build.gradle
o el enfoque no funcionará en versiones antiguas de Android.
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
2. Hardcode creando
StateListDrawable
El enfoque es adecuado si utiliza para los dibujos vectoriales de la lista de estados que difieren no solo en un color sino también en una figura, por lo que debe crear varios archivos xml diferentes.
Luego puede crear
StateListDrawable
programación como se muestra en una
answer
.
Después de ver
Novedades en la biblioteca de soporte: Google I / O 2016
, noté un método útil en la clase
AppCompatResources
.
Esta es
AppCompatResources#getColorStateList(Context context, int resId)
.
Con la ayuda de este método, he implementado el selector con vectores dibujables.
Aquí está mi archivo selector de color
icon_selector
:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/red_selected" android:state_selected="true"/>
<item android:color="@color/red_pressed" android:state_pressed="true"/>
<item android:color="@color/red"/>
</selector>
Y hay un método java que devuelve dibujable teñido:
private Drawable getTintedDrawable(@DrawableRes int drawableId) {
Drawable drawable;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
drawable = getResources().getDrawable(drawableId, getTheme());
} else {
drawable = getResources().getDrawable(drawableId);
}
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTintList(drawable.mutate(), AppCompatResources.getColorStateList(this, R.color.selector_nav_bar_item_ico));
return drawable;
}
Puedes usarlo como se muestra a continuación
yourImageView.setImageDrawable(getTintedDrawable(R.drawable.ic_vector_image));
Funciona bien con los siguientes cambios.
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Agregado en la clase de aplicación.
app build.gradle dentro de defaultConfig
vectorDrawables.useSupportLibrary = true