旧设备Android资源ID找不到:矢量图作为背景的适配问题求助
嘿,我之前也踩过这个Android矢量图当背景的坑!确实,app:srcCompat只对ImageView的src属性生效,直接给View设置矢量图背景用setBackgroundResource()或者android:background在低版本系统上很容易崩,给你几个亲测有效的解决办法:
1. 用ImageView做背景容器(最省心的方案)
把需要背景的View嵌套在一个ImageView里,给这个ImageView用app:srcCompat设置矢量图,然后把你的内容View叠在上面。这样既利用了AppCompat对矢量图的完美兼容,又能实现背景效果。示例布局代码:
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 作为背景的ImageView --> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" app:srcCompat="@drawable/your_vector_bg" android:scaleType="centerCrop"/> <!-- 按需调整缩放类型,比如fitXY、center等 --> <!-- 你的实际内容View --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="这是叠加在矢量背景上的内容"/> </LinearLayout> </FrameLayout>
2. 代码中把矢量图转成BitmapDrawable再设背景
如果不想嵌套布局,可以在代码里手动把矢量图转换成BitmapDrawable,再给View设置背景。这样能避开系统对矢量背景的兼容问题,示例代码:
Kotlin版本
val vectorDrawable = AppCompatResources.getDrawable(context, R.drawable.your_vector_bg) ?: return // 创建和矢量图尺寸一致的Bitmap val bitmap = Bitmap.createBitmap( vectorDrawable.intrinsicWidth, vectorDrawable.intrinsicHeight, Bitmap.Config.ARGB_8888 ) val canvas = Canvas(bitmap) // 绘制矢量图到Bitmap上 vectorDrawable.setBounds(0, 0, canvas.width, canvas.height) vectorDrawable.draw(canvas) // 设置为背景 yourTargetView.background = BitmapDrawable(resources, bitmap)
Java版本
Drawable vectorDrawable = AppCompatResources.getDrawable(context, R.drawable.your_vector_bg); if (vectorDrawable == null) return; // 创建Bitmap Bitmap bitmap = Bitmap.createBitmap( vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); // 绘制矢量图 vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); vectorDrawable.draw(canvas); // 设置背景 yourTargetView.setBackground(new BitmapDrawable(getResources(), bitmap));
小提示:如果你的View尺寸和矢量图不一样,可以根据View的宽高调整Bitmap的大小,避免背景拉伸变形。
3. 配置兼容后直接用android:background(慎用)
如果你的项目已经配置了AppCompat矢量图兼容,也可以直接尝试android:background="@drawable/your_vector_bg",但这个方法在部分老系统(API<21)或者复杂View上可能还是会崩,需要先确认配置:
- 在Module级别的
build.gradle里添加:
android { defaultConfig { vectorDrawables.useSupportLibrary = true } }
- 若在非AppCompat主题或自定义View中,还需要在Application的
onCreate()里开启兼容:
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
为啥直接用setBackgroundResource()会报错?
原因很简单:API 21以下的Android系统原生不支持将矢量图作为background资源加载,而app:srcCompat是AppCompat库专门为ImageView的src属性做的兼容方案,对background属性完全不起作用,所以直接调用setBackgroundResource()加载矢量图就会触发崩溃。
内容的提问来源于stack exchange,提问作者Adrian Coutsoftides

