如何在Android VectorDrawable中无需<filter>标签模拟内阴影效果
模拟内阴影(无Filter)实现Android Vector Drawable自适应图标
完全理解你的需求——因为Android的Vector Asset Studio确实不支持SVG的<filter>元素,尤其是投影、模糊这类滤镜,所以我们得用渐变+形状布尔运算的方式来模拟内阴影效果。下面我会分工具操作步骤和最终的Vector Drawable代码来讲解,完全符合你的要求(不用PNG,纯XML矢量)。
核心原理
内阴影本质是形状内部边缘的深色半透明渐变,不用filter的话,我们可以通过以下思路实现:
- 创建一个比原形状稍大一圈的"扩展形状"(大小对应阴影的宽度)。
- 用原形状作为遮罩,裁剪掉扩展形状的中间部分,只留下边缘的"阴影轮廓"。
- 给这个阴影轮廓添加从半透明深色到完全透明的渐变,模拟阴影的衰减效果。
- 将阴影层放在原形状的下方,就会呈现出内阴影的视觉效果。
工具实现步骤(优先Inkscape & Affinity Designer)
方法1:Inkscape操作
- 打开你提供的SVG文件,选中应用了filter的
<g>组(也就是包含4个蓝色路径的群组)。 - 复制这个群组,粘贴到原群组的下方,作为阴影层。
- 选中阴影层的所有路径,执行「路径 → 偏移路径」:
- 偏移量设为
1px(对应你原filter里的stdDeviation="1",可根据效果调整)。 - 方向选择「向外」。
- 偏移量设为
- 同时选中原群组和偏移后的阴影层,执行「路径 → 差集」——这一步会把阴影层裁剪成只有原形状向外扩展的边缘部分。
- 给差集后的路径添加线性渐变:
- 起始色:
#000000(黑色),透明度50%(对应原filter的flood-opacity=".5")。 - 结束色:完全透明(
#00000000)。 - 渐变方向:从左上到右下(对应原filter的
dx="-1" dy="1",模拟左上方向的内阴影)。
- 起始色:
- 把阴影层移动到原群组的下方,微调渐变的偏移量或透明度,直到效果和原filter一致。
方法2:Affinity Designer操作
- 导入你的SVG,选中目标图形群组。
- 复制群组并粘贴到下方作为阴影层。
- 选中阴影层,点击工具栏的「偏移」工具:
- 设置偏移量为
1px,方向「向外」。
- 设置偏移量为
- 同时选中原群组和偏移后的阴影层,点击「布尔运算 → 减去顶层」,得到阴影轮廓。
- 给阴影轮廓添加渐变填充:
- 起始色:
#00000080(半透明黑),结束色:#00000000(全透明)。 - 调整渐变角度为
135°(对应左上到右下的方向)。
- 起始色:
- 将阴影层置于原图形下方,微调参数匹配原内阴影效果。
修改后的Vector Drawable代码(无Filter)
我已经把你的原SVG改造为符合Android Vector Drawable规范的代码,替换了filter部分,用渐变模拟内阴影:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="108dp" android:height="108dp" android:viewportWidth="108" android:viewportHeight="108"> <defs> <!-- 内阴影渐变:模拟左上方向的半透明阴影衰减 --> <linearGradient android:id="innerShadowGradient" android:startX="0%" android:startY="0%" android:endX="100%" android:endY="100%"> <stop android:offset="0%" android:color="#000000" android:alpha="0.5"/> <stop android:offset="100%" android:color="#000000" android:alpha="0.0"/> </linearGradient> </defs> <!-- 背景层 --> <path android:fillColor="#73e8ff" android:pathData="M0,0h108v108h-108z"/> <!-- 内阴影层:原图形偏移后的差集路径 --> <path android:fill="@drawable/innerShadowGradient" android:pathData="M37.58,24.16l9.8,7.12L44.83,39.1h-12.07l-3.73-7.82L37.58,24.16ZM20.11,58.19l4.93,3.66L23.4,64.14l4,1.28L25.12,69.3l-4,1.28v4.16h-6v-4.16l-4-1.28L12.1,64.14l4-1.28L12.1,58.19l4.93-3.54L18.1,61.1l2.01-3.09ZM42.05,62.45a9.58,9.58 0 1,1 0,19.16a9.58,9.58 0 0,1 0,-19.16Zm0,4.78a4.8,4.8 0 1,1 0,9.58a4.8,4.8 0 0,1 0,-9.58ZM64.5,33.12c2.16-3.1,6.49-3.1,8.65-1.54c2.16,1.54 2.16,4.63 0,7.73c-1.53,2.31-5.43,4.63-8.65,6.15c-3.23-1.53-7.14-3.87-8.65-6.15c-2.16-3.1-2.16-6.2,0-7.73c2.16-1.54,6.49-1.54,8.65,1.54Z"/> <!-- 原图形组 --> <g> <path android:fillColor="#29b6f6" android:pathData="M53.63,37l6.66,4.84L57.74,49.66h-8.23L47.03,41.84L53.63,37Z" android:translateX="-36.72" android:translateY="-23.11" android:scaleX="1.47134" android:scaleY="1.47134"/> <path android:fillColor="#29b6f6" android:pathData="M21.66,56.7L25,59.14l-1.66,2.29l2.7,0.87l-1.28,3.92l-2.7,-0.88v2.83h-4.1v-2.83l-2.7,0.88l-1.27,-3.92l2.7,-0.87l-1.67,-2.3l3.33,-2.41L20,59l1.66,-2.3Z" android:rotation="180" android:pivotX="38.98" android:pivotY="89" android:scaleX="1.78662" android:scaleY="1.78662"/> <path android:fillColor="#29b6f6" android:pathData="M46.5,64a6.5,6.5 0 1,1 0,13a6.5,6.5 0 0,1 0,-13Zm0,3.25a3.25,3.25 0 1,1 0,6.5a3.25,3.25 0 0,1 0,-6.5Z" android:translateX="-7.45" android:translateY="-45.56" android:scaleX="1.58452" android:scaleY="1.58452"/> <path android:fillColor="#29b6f6" android:pathData="M71,35.69c1.47,-2.1 4.42,-2.1 5.9,-1.05c1.47,1.05 1.47,3.15 0,5.25c-1.04,1.57 -3.69,3.15 -5.9,4.2c-2.21,-1.05 -4.86,-2.63 -5.9,-4.2c-1.47,-2.1 -1.47,-4.2 0,-5.25c1.48,-1.05 4.43,-1.05 5.9,1.05Z" android:scaleX="1.47134" android:scaleY="1.96178" android:translateX="-38.24" android:translateY="-35.06"/> </g> </vector>
代码说明:
- 移除了原SVG的
<filter>元素,改用<linearGradient>模拟阴影衰减。 - 阴影层是原图形向外偏移1px后与原图形的差集路径,应用渐变后放在原图形下方。
- 所有属性都转换为Android Vector Drawable的规范(比如
android:前缀,fillColor替代fill等),可以直接放在drawable-anydpi-v26目录下使用。
内容的提问来源于stack exchange,提问作者ivadham
相关产品推荐
相关产品推荐

