我有一个AppWidget,想要在其中使用VectorDrawables,包括在Lollipop之前的设备上。
VectorDrawableCompat无法与我创建的RemoteViews一起使用。
为了让我的应用程序APK大小保持不变,我不想为旧的API平台添加可替代的PNG版本的drawables。
我该怎么做?
为了让我的应用程序APK大小保持不变,我不想为旧的API平台添加可替代的PNG版本的drawables。
我该怎么做?
更新于 2017年10月22日
正如 @user924 所指出的,现在 AppCompatDrawableManager 访问被限制为其自己的库。 ContextCompat.getDrawable(...) 应该能解决问题。
更新于 2016年9月5日
正如 @kirill-kulakov 在其答案中所指出的,支持库的最新更新将 TintContextWrapper 的可见性限制为其自己的包。
我正在更新我的答案以删除不正确的代码,但请感谢 Kirill 提供的纠正!
您可以通过使用 TintContextWrapper 和 ContextCompat 来避免添加矢量可绘制资源的替代位图版本。在早期的 Android 版本中,这个类可以解析 VectorDrawable 的 XML 文件并将它们转换成可以在 API 7 及以上版本中使用的 VectorDrawableCompat 实例。
然后,一旦您获得了一个 VectorDrawableCompat 实例,请将其栅格化到位图上。稍后您将在远程的 ImageView 中使用此位图。
请确保您使用的是 Android Studio 2.0 或更高版本,并已按照以下方式配置了您的应用程序build.gradle
文件:
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.3.0'
}
首先:不要在您的RemoteViews布局文件中设置矢量可绘制资源(无论是android:src
还是app:srcCompat
都将无法工作)。您需要以编程方式设置它们。
在您的AppWidgetProvider类中根据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);
}
矢量图
转换为位图,这应该可以解决问题。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;
}
AppCompatDrawableManager can only be called from within the same library group
- user924