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.
- Coracteres corrompidos o desaparecidos después de ejecutar Proguard
- ¿Puedo usar el archivo vectorial dibujable en el icono del menú de ActionBar?
- Cómo crear Android VectorDrawables de Illustrator (u otra herramienta similar)?
- AnimatedVectorDrawable no anima
- ¿Puedo usar un vector dibujable de la misma manera que usé un parche 9?
¿Cómo puedo hacer eso?
- Animado (VectorDrawable) animado mediante programación en tiempo de ejecución
- Vector de etiqueta dibujable no válido
- ¿Hay una manera de escuchar el final de la animación en AnimatedVectorDrawables
- Android Layer-List VectorDrawable tamaño
- Cambiar fillColor de vector en android programaticamente
- ¿Existe una manera sencilla de medir la distancia entre un punto y un grupo VectorDrawable?
- Descripción de las propiedades VectorDrawable de Android
- Problema de renderización de VectorDrawable
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; }