xmlns vectordrawables usesupportlibrary true support srccompat last enable drawables android vector android-support-library appcompat-v7-r23 android-appcompat android-vectordrawable

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