Android VectorDrawable 不支持 clip-path,仅可用 trimPathStart/trimPathEnd 实现路径局部显隐,或多路径分组配合 scale/translate 模拟遮罩,需通过 AnimatedVectorDrawable 驱动动画。

clip-path 在 Android VectorDrawable 中根本不可用
Android 原生 VectorDrawable 不支持 clip-path 属性,哪怕写进 XML 也会被完全忽略。这不是版本兼容问题,而是 SVG 子集规范里压根没包含它 —— AAPT2 编译时不会报错,但运行时无效,图标该全显还是全显。
常见错误现象:android:clipPath 写在 <group> 或 <path> 上,预览器可能显示正常,真机一跑就失效;或者用第三方库(如 androidsvg)加载含 clip-path 的 SVG,结果路径被裁剪但动画无法驱动。
- VectorDrawable 支持的裁剪只有
android:trimPathStart/trimPathEnd和android:pathData自身构造的封闭区域 - 想局部显隐,得靠「路径拆分 + group 变换」或「mask 路径模拟」,而不是直接套用 SVG 的
clip-path - Android 12+ 的
AnimatedVectorDrawable仍不支持动态更新 clip-path,别试
用 trimPathStart/trimPathEnd 实现“擦除式”局部显隐
这是最稳妥、兼容性最好的方案,本质是控制路径绘制起点和终点比例(0.0–1.0),适合线性展开/收缩类动效,比如箭头弹出、勾选动画、进度指示。
使用场景:单条路径构成的图标(如 check、arrow_back)、需要从左到右/从下到上逐步显现的图形。
-
trimPathStart控制起始裁剪位置(0.0 = 不裁,1.0 = 全裁) -
trimPathEnd控制结束裁剪位置(0.0 = 全裁,1.0 = 不裁) - 两者差值即为可见段长度,比如
trimPathStart="0.3" trimPathEnd="0.8"显示中间 50% - 动画必须通过
AnimatedVectorDrawable驱动,不能直接在VectorDrawable里设初始值后手动改
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group android:name="check_group">
<path
android:name="check_path"
android:pathData="M4,12 L9,17 L19,7"
android:strokeWidth="2"
android:strokeColor="#000"
android:trimPathStart="0"
android:trimPathEnd="0" />
</group>
</vector>
多路径 + group scale/translate 模拟局部遮罩
当图标由多个独立路径组成(比如一个圆圈 + 一个对勾),又想只让其中一部分“渐显”,就得放弃单路径裁剪思路,转而用 <group> 做视觉遮罩:把要隐藏的部分缩放为 0 或平移出视口,再配合透明度或颜色变化实现“局部显隐”感。
性能影响小,但需手动拆分原始路径;容易踩的坑是 viewport 对齐和坐标偏移算错,导致动画错位。
- 把原图标所有路径按“是否参与显隐”分组,每组放进独立
<group> - 对要隐藏的组,用
android:pivotX/pivotY配合android:scaleX实现收缩消失(如scaleX="0") - 避免用
android:translateX移出太远(比如 -100dp),某些低版本会因裁剪失效导致残影 - 若需“圆形遮罩”效果(如中心放大),只能靠两层 path:底层画圆 mask,顶层用
android:fillType="evenOdd"扣出中间区域
AnimatedVectorDrawable 动画配置的关键细节
真正让局部显隐动起来的不是 vector XML,而是配套的 animated-vector 和 animator 文件。漏掉任一环,动画就不触发。
最容易被忽略的是属性名拼写和 target 匹配 —— 名字大小写、下划线、group/path 名必须一字不差,否则静默失败。
-
<target android:name="check_path">中的 name 必须和 vector 里android:name完全一致 - 动画属性名写成
android:trimPathStart,不是trimPathStart(缺android:前缀会无效) - 使用
ValueAnimator.ofFloat()时,起止值必须是浮点数(0f,1f),整数会导致类型不匹配 - 如果动画卡在某一帧,先检查
android:duration是否设为 0,或android:fillAfter="true"覆盖了最终状态
clip-path,也别指望用一层 vector 解决所有情况。路径结构、动画节奏、目标 API 级别这三者得一起看——有时候拆成两个 vector 分别控制,反而比硬塞进一个带 mask 的复杂方案更稳。










