Selector de Android Drawable con VectorDrawables srcCompat

Estoy enfrentando un problema con la nueva compatibilidad hacia atrás con VectorDrawables. En la Biblioteca de Soporte 23.2 fue una nueva característica para la compatibilidad con Android VectorDrawables indroduced.

Tengo un ImageView que es un SelectorDrawable asignado a. Este Drawable tiene varios VectorDrawables por lo que pensé que debería usar app: srcCompat para la 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 drawables son archivos vectoriales xml.

Al usar este SelectorDrawable con srcCompat obtengo 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 utilizo uno de los dibujos vectoriales con app: 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 no es posible utilizar VectorDrawables en SelectorDrawables antes de Android 5?

Los Hechos Rápidos:

  • Compilar API de destino 23
  • Apoyo Libraray 23.3.0
  • VectorDrawables.useSupportLibrary = true
  • Gradle 2.0

Algunas cosas han cambiado desde que hice esta pregunta así que contestaré yo mismo.

Con Support Library 23.4.0 se volvió a habilitar el soporte para VectorDrawables de Ressources: Android Support Library 23.4.0 ya está disponible

Puede encontrar más información sobre este tema en Google I / O 2016: ¿Qué hay de nuevo en la biblioteca de soporte técnico? Google I / O 2016

Debe agregar esto a cada actividad en la que desee utilizar VectorDrawables en dispositivos inferiores a Android 5:

 static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); } 

Así que ahora puede utilizar VectorDrawables en DrawableContainers, pero todavía puede causar algunos problemas como se menciona en las fuentes anteriores, así que úselo con precaución.

No reactivé esta función en mi aplicación hasta ahora, pero cambiaré muchos de mis iconos a VectorDrawables con mi próximo lanzamiento principal y luego me sumergiré más en este tema.

Como @Jahnold mencionó en el comentario a la pregunta, el soporte para cargar vector dibujable de una lista xml estado xml fue eliminado en 23.3.

Sin embargo, he encontrado varios enfoques que pueden ayudar.

1. Uso de Tinte

El acercamiento es conveniente si los estirables del estado seleccionado enumeran la diferencia solamente por colores.

En primer lugar, crear sólo un vector dibujable con tinte y blanco 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> 

Segundo, cree la lista de estado de color button_tint.xml colocada 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 se olvide de añadir seguir las líneas de build.gradle o el enfoque no funcionará en versiones antiguas de Android.

 defaultConfig { vectorDrawables.useSupportLibrary = true } 

2. Hardcode creando StateListDrawable

El acercamiento es conveniente si usted utiliza para el estado lista el vector drawables que diferencia no sólo un color pero también por una figura así que usted necesita crear varios diversos archivos del xml. A continuación, puede crear StateListDrawable programación como se muestra en una respuesta .

Después de ver Qué hay de nuevo en la biblioteca de soporte – Google I / O 2016 He notado un método más útil en la clase AppCompatResources . Esto es AppCompatResources#getColorStateList(Context context, int resId) . Con una ayuda de este método he implementado selector con dibujos vectoriales. 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 teñido dibujable:

  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)); 
  • ¿Dónde puedo ir para las imágenes de Android Market? Una imagen vacía de la tableta que puedo pegar mi aplicación en ejecución en un gráfico promocional sería perfecto
  • La imagen VectorDrawable se pixeliza
  • VectorDrawable - ¿está disponible de alguna manera para versiones pre-Lollipop de Android?
  • Android studio 1.4 y la imagen vectorial
  • Dirección de aceleración lineal para realizar un seguimiento del movimiento hacia arriba y hacia abajo del teléfono
  • Usando el vector android Dibujos en el accidente antes de Lollipop
  • XmlPullParserException: vector de etiqueta desplegable no válido
  • Error de soporte del vector de Android
  • Vector Drawable como el logotipo de la aplicación
  • ¿Son útiles las imágenes vectoriales para Android?
  • Cambiar fillColor de vector en android programaticamente
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.