我尝试使用以下代码加载XML vector vector:
int px = Application.get().getResources()
.getDimensionPixelSize(R.dimen.bikeshare_small_marker_size);
Bitmap bitmap = Bitmap.createBitmap(px, px, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
Drawable shape = ContextCompat.getDrawable(Application.get(), R.drawable.bike_marker_small);
shape.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
shape.draw(c);
以下是bike_marker_small.xml
文件:
<vector android:height="24dp" android:viewportHeight="210.0"
android:viewportWidth="210.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ffffff"
android:pathData="M105.03,104.97m-53.84,0a53.84,53.84 117.34,1 1,107.67 0a53.84,53.84 117.34,1 1,-107.67 0"
android:strokeAlpha="1" android:strokeColor="#3a4677" android:strokeWidth="1.46500003"/>
<path android:fillAlpha="1" android:fillColor="#3a4677"
android:pathData="M105.1,104.67m-47.53,0a47.53,47.53 118.07,1 1,95.06 0a47.53,47.53 118.07,1 1,-95.06 0"
android:strokeAlpha="1" android:strokeColor="#000000" android:strokeWidth="0.26458332"/>
</vector>
在Android 6,7和8上,这很好用。但是,当我尝试在API 19(Android 4.4)模拟器或设备上运行应用程序时,我得到以下内容:
android.content.res.Resources$NotFoundException: File res/drawable/bike_marker_small.xml from drawable resource ID #0x7f08005f.
If the resource you are trying to use is a vector resource, you may be referencing it in an unsupported way.
See AppCompatDelegate.setCompatVectorFromResourcesEnabled() for more info.
at android.content.res.Resources.loadDrawable(Resources.java:2101)
at android.content.res.Resources.getDrawable(Resources.java:700)
at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:353)
at org.onebusaway.android.map.googlemapsv2.bike.BikeStationOverlay.createBitmapFromShape(BikeStationOverlay.java:195)
at org.onebusaway.android.map.googlemapsv2.bike.BikeStationOverlay.(BikeStationOverlay.java:87)
at org.onebusaway.android.map.googlemapsv2.BaseMapFragment.setupBikeStationOverlay(BaseMapFragment.java:474)
我的build.gradle
中有以下内容:
android {
compileSdkVersion 27
buildToolsVersion "26.0.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21
versionCode 86
versionName "2.3.1"
vectorDrawables.useSupportLibrary = true
}
...
为什么这不起作用?
答案 0 :(得分:9)
尝试使用shape
代替VectorDrawableCompat.create()
创建可绘制的ContextCompat.getDrawable()
:
Drawable shape = VectorDrawableCompat.create(
Application.get().getResources(),
R.drawable.bike_marker_small,
Application.get().getTheme()
);
答案 1 :(得分:1)
Sean Barbeau的回答肯定很棒,尽管我想补充一下发生在我身上的事情,这可能会给其他人带来麻烦,试图弄清楚API 19或API 20上的VectorDrawable
是怎么回事
我创建了一种方法,用于在不需要/想要将VectorDrawable
用作Drawable
的情况下将Drawable
用作Bitmap
的情况例。此方法适用于> = API 19的Android版本。
这是Kotlin方法(请看最后的改进版本):
fun getDrawable(context:Context, drawableId: Int): Drawable {
var drawable: Drawable?
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
drawable = VectorDrawableCompat.create(context.resources, drawableId, context.theme)
} else {
drawable = ContextCompat.getDrawable(context, drawableId)
}
return drawable
}
基本上,我传递上下文(因为该方法将是辅助方法,并且将在没有Context
或Activity
的类中)和VectorDrawable
的资源ID
可能会发生,您可以使用R名称空间直接使用资源ID调用此辅助方法,如下所示:
ImageUtils.Companion.getDrawable(
getBaseContext(),
R.drawable.your_vector_drawable
)
但是,也可以动态生成资源ID,类似于:
@DrawableRes val resourceID = context.resources.getIdentifier(
"resource_prefix_" + type,
"drawable",
context.packageName
)
然后使用resourceID变量,以与以前相同的方式调用helper方法:
ImageUtils.Companion.getDrawable(
getBaseContext(),
resourceID
)
如果以此方式进行操作,则在API <21上时,动态生成的资源ID很可能是PNG。并且辅助方法将失败,因为它期望使用XML(SVG)。您可以通过请求普通的Drawable
(而不是VectorDrawable
),捕获将要引发的NotFoundException
并得到一个Drawable
来解决此问题。这是最终的帮助方法:
fun getDrawable(context:Context, drawableId: Int): Drawable {
var drawable: Drawable?
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
try {
drawable = VectorDrawableCompat.create(context.resources, drawableId, context.theme)
} catch (ex: Resources.NotFoundException) {
drawable = ContextCompat.getDrawable(context, drawableId)
}
} else {
drawable = ContextCompat.getDrawable(context, drawableId)
}
return drawable
}
答案 2 :(得分:0)
您应该使用AppCompatResources.getDrawable(context, R.drawable.drawable_id);
来内部完成所有操作。
此功能适用于:
Drawables
s VectorDrawable
,AnimatedVectorDrawable
s AnimatedStateListDrawable
s 您需要appcompat库才能做到这一点