VectorDrawable在API21不显示/绘制异常技术求助
解决API21上自定义VectorDrawable不显示的问题
这个问题很典型——Android 5.0(API21)到7.0(API24)对VectorDrawable的path语法支持有不少限制,尤其是自定义手写的pathData很容易踩坑。结合你的情况,PSD生成的矢量图正常,自定义的剑形和绶带形不显示,大概率是pathData里用了低版本不兼容的语法或者简写。我给你一步步解决:
1. 先确保AppCompat兼容配置正确
低版本系统本身不支持直接在ImageView/ImageButton中使用VectorDrawable,必须依赖AndroidX的AppCompat库来做兼容:
- 首先在Module级别的
build.gradle中启用矢量图支持:
android { defaultConfig { // 启用VectorDrawable兼容库 vectorDrawables.useSupportLibrary = true } } dependencies { // 确保依赖最新的AppCompat库 implementation 'androidx.appcompat:appcompat:1.6.1' }
- 把布局中的原生
ImageButton替换为androidx.appcompat.widget.AppImageButton:
比如你的multiplayerButton布局改成:
<androidx.appcompat.widget.AppImageButton android:id="@+id/multiplayerButton" android:layout_width="0dp" android:layout_height="80dp" android:layout_marginTop="4dp" android:background="@drawable/rounded_corners" android:paddingBottom="2dp" android:paddingTop="2dp" android:scaleType="fitCenter" android:src="@drawable/button_multiplayer_icon" app:layout_constraintEnd_toEndOf="@id/guideline3" app:layout_constraintStart_toStartOf="@id/guideline2" app:layout_constraintTop_toBottomOf="@id/startButton" />
- 可选:在Application类的
onCreate方法中全局启用矢量图兼容:
@Override public void onCreate() { super.onCreate(); AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); }
2. 修正自定义VectorDrawable的pathData
API21对pathData的简写语法(比如连续的相对命令、无空格分隔的参数)支持很差,你提供的两个异常矢量图都存在这类问题。我们可以把相对命令换成绝对命令,拆分复杂路径,让低版本系统能正确解析:
修正后的剑形矢量图:
<vector android:height="24dp" android:viewportHeight="512" android:viewportWidth="512" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="@color/menu_buttons" android:name="ic multiplayer" android:fillType="nonZero" android:pathData="M468.9,41.5 L395.8,57 L268.6,196.4 L311.7,243.7 L453.3,114.5 L468.8,41.4 Z M201.4,270.1 L145.6,331.3 L116.9,302.6 L88.1,331.3 L108.1,351.3 L38.6,420.8 L90.2,472.4 L159.6,402.9 L179,422.2 L207.7,393.5 L179,364.8 L242,307.3 L201.3,270.1 Z M43,41.5 L58.6,114.6 L332.9,364.9 L304.2,393.6 L333,422.4 L352.3,403.1 L421.8,472.6 L473.4,421 L404,351.5 L424,331.5 L395.2,302.8 L366.5,331.5 L116.2,57.2 L43.1,41.7 Z"/> </vector>
修正后的绶带形矢量图:
<vector android:height="24dp" android:viewportHeight="512" android:viewportWidth="512" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="@color/menu_buttons" android:name="ic achievements" android:fillType="nonZero" android:pathData="M256.3,343.9 L303.5,365.8 L326.5,331.6 L381.8,435.6 L312,503.9 L256.3,343.9 Z M255.6,343.9 L208.4,365.8 L185.5,331.6 L130.2,435.6 L199.9,503.9 L255.6,343.9 Z M256,47.4 L299.1,27.4 L326.5,66.3 L373.8,70.5 L378,117.9 L416.9,145.2 L396.9,188.3 L416.9,231.4 L378,204 L373.8,251.3 L326.5,255.5 L299.1,217.6 L256,237.6 L212.9,217.6 L185.5,255.5 L138.2,251.3 L134,204 L95.1,231.4 L115.1,188.3 L95.1,145.2 L134,117.9 L138.2,70.5 L185.5,66.3 L212.9,27.4 L256,47.4 Z M256.2,95.9 C205.4,95.9 164.1,137.1 164.1,187.9 C164.1,238.8 205.4,280 256.2,280 C307,280 348.2,238.8 348.2,187.9 C348.2,137.1 307,95.9 256.2,95.9 Z"/> </vector>
3. 更稳妥的方案:用Vector Asset Studio重新生成
如果手动修改pathData太麻烦,你可以把自定义的矢量图(比如SVG格式)导入Android Studio的Vector Asset Studio,它会自动生成兼容低版本的pathData:
- 右键点击
res/drawable目录 → New → Vector Asset - 选择"Local file (SVG, PSD)",导入你的矢量图文件
- 生成后的VectorDrawable会自动处理兼容问题,API21上就能正常显示了
为什么PSD生成的矢量图没问题?
因为谷歌提供的PSD文件生成的VectorDrawable,已经经过了Vector Asset Studio的兼容处理,pathData都是低版本能解析的语法,所以不会出现显示异常。
内容的提问来源于stack exchange,提问作者Oliver Nybroe
相关产品推荐
相关产品推荐

