AppCompat 23.2 utiliza VectorDrawableCompat con RemoteViews (AppWidget) en la API <21

Tengo un AppWidget y me gustaría utilizar VectorDrawables en él también en dispositivos pre-Lollipop. VectorDrawableCompat no funcionará con las RemoteViews que creo.

Para mantener el tamaño de APK de la aplicación reducido, no quiero añadir versiones alternativas de PNG de mis drawables para las plataformas de API más antiguas.

¿Cómo puedo hacer eso?

ACTUALIZACIÓN 05/09/2016

Como lo señaló @ kirill-kulakov en su respuesta, las últimas actualizaciones de la Biblioteca de Soporte restringieron la visibilidad de TintContextWrapper a su propio paquete. Estoy actualizando mi respuesta para eliminar el código incorrecto, pero gracias a Kirill por la corrección!

VectorDrawable y RemoteViews pre-Lollipop

Puede evitar la adición de versiones rasterizadas alternativas de sus recursos dibujables con un hack fácil: use AppCompat TintResources a través de TintContextWrapper usando AppCompatDrawableManager .

TintResources AppCompatDrawableManager es la clase que, entre otras cosas, en dispositivos pre-Lollipop, analiza los archivos XML de VectorDrawable y los convierte en instancias de VectorDrawableCompat que se pueden utilizar hasta la API 7.

A continuación, una vez que tenga una instancia de VectorDrawableCompat , rasterize en un mapa de bits. Más adelante utilizarás este mapa de bits en un ImageView remoto.

Antes de comenzar: AppCompat Library

Asegúrese de que utiliza Android Studio 2.0+ y ha configurado su archivo build.gradle la siguiente manera:

 android { defaultConfig { vectorDrawables.useSupportLibrary = true } } dependencies { compile 'com.android.support:appcompat-v7:23.3.0' } 

Actualiza tu AppWidgetProvider

En primer lugar: no establezca los recursos dibujables del vector dentro del archivo de diseño RemoteViews (ni android:src ni app:srcCompat funcionará). Tendrás que configurarlas mediante programación.

Dentro de su clase AppWidgetProvider , establezca el recurso vectorial o una versión rasterizada en función del nivel de la API:

 RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { remoteViews.setImageViewResource(R.id.imageView, R.drawable.vector); } else { Drawable d = AppCompatDrawableManager.get().getDrawable(context, R.drawable.vector); Bitmap b = Bitmap.createBitmap(d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); d.setBounds(0, 0, c.getWidth(), c.getHeight()); d.draw(c); remoteViews.setImageViewBitmap(R.id.imageView, b); } 

Referencias

  • Código fuente AppCompatDrawableManager
  • AppCompat de Chris Banes ' v23.2 – La entrada de blog Age of the vectors introduce VectorDrawableCompat y explica el hack que AppCompat utiliza para hacerlos trabajar en dispositivos pre-Lollipop.

El método siguiente convertirá el vector drawable a un mapa de bits antes, esto debe hacer el truco.

 public static BitmapDrawable vectorToBitmapDrawable(Context ctx, @DrawableRes int resVector) { return new BitmapDrawable(ctx.getResources(), vectorToBitmap(ctx, resVector)); } public static Bitmap vectorToBitmap(Context ctx, @DrawableRes int resVector) { Drawable drawable = AppCompatDrawableManager.get().getDrawable(ctx, resVector); Bitmap b = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); drawable.setBounds(0, 0, c.getWidth(), c.getHeight()); drawable.draw(c); return b; } 
  • ¿Cómo tener un selector de dibujos vectoriales?
  • Cómo cambiar el color de la trayectoria del vector drenable en el botón de clic
  • ¿Cómo hacer que el vector de una aplicación extraiga el vector de una biblioteca?
  • Android: Cómo establecer el color de trazo para el vector dibujable mediante programación
  • Cómo preservar la relación de aspecto de VectorDrawable?
  • Cambiar el color de relleno del elemento vectorial en Android Studio
  • Cómo centrar el vector dibujable en la lista de capas sin escala
  • VectorDrawable no se representa correctamente en API 23
  • Android Vector Drawable accidente
  • ¿Podemos usar VectorDrawable o VectorXML como iconos para notificaciones push en android?
  • ¿Cómo puedo utilizar vectorDrawable como icono para notificaciones push mediante Android Support Library 23.2? setSmallIcon da error
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.