android - AppCompat 23.2 usa VectorDrawableCompat con RemoteViews(AppWidget) en la API<21
android-support-library (2)
El siguiente método convertirá el vector drawable
a un mapa de bits antes, esto debería 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;
}
Tengo un AppWidget y me gustaría usar VectorDrawables también en dispositivos pre-Lollipop. VectorDrawableCompat no funcionará con las RemoteViews que creo.
Para mantener el tamaño de mi APK de la aplicación, no quiero agregar versiones PNG alternativas de mis dibujables para plataformas API más antiguas.
¿Cómo puedo hacer eso?
ACTUALIZACIÓN 22/10/2017
Como lo señaló @ user924, ahora el acceso a AppCompatDrawableManager está restringido a su propia biblioteca. ContextCompat.getDrawable (...) debería hacer el truco.
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 agradezca a Kirill por la corrección!
VectorDrawable y RemoteViews pre-Lollipop
Puede evitar agregar versiones rasterizadas alternativas de sus recursos dibujables vectoriales con un simple truco : use AppCompat TintResources a través de TintContextWrapper usando AppCompatDrawableManager usando ContextCompat .
TintResources AppCompatDrawableManager ContextCompat es la clase que, entre otras cosas, en los dispositivos pre-Lollipop, analiza los archivos XML de VectorDrawable y los convierte en instancias de VectorDrawableCompat que pueden utilizarse hasta API 7.
Luego, una vez que tenga una instancia de VectorDrawableCompat , rasterícelo en un mapa de bits. Más adelante utilizará este mapa de bits en un ImageView remoto.
Antes de comenzar: AppCompat Library
Asegúrese de que está utilizando Android Studio 2.0+ y que haya configurado su aplicación build.gradle
file de la siguiente manera:
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
dependencies {
compile ''com.android.support:appcompat-v7:23.3.0''
}
Actualice su AppWidgetProvider
En primer lugar: no configure sus recursos dibujables vectoriales dentro de su archivo de diseño de RemoteViews (ni android:src
ni app:srcCompat
funcionarán). Tendrás que configurarlas programáticamente.
Dentro de su clase AppWidgetProvider , establezca el recurso vectorial o una versión rasterizada según el nivel de 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 = ContextCompat.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 de ContextCompat
- AppCompat v23.2 de Chris Banes - La era del blog de vectores de vectores introduce VectorDrawableCompat y explica el truco que utiliza AppCompat para hacer que funcionen en dispositivos pre-Lollipop.