XML中虚线不生效主因是未设android:shape="line"或rectangle下未加android:useLevel="false";dashWidth与dashGap需成对使用、单位为dp、比值决定虚实节奏;API 21以下不支持;布局溢出会导致截断。

stroke dashWidth 和 dashGap 在 XML 中不起作用?
多数时候不是写错了,而是没加 android:shape="line" 或者用了 rectangle 却漏了 android:useLevel="false"。虚线只对 line 和带 stroke 的 rectangle 有效,但后者必须显式关掉 level 行为,否则 dash 效果被忽略。
-
android:shape="line"是最稳妥的选择,专为线条设计,dashWidth/dashGap 直接生效 -
android:shape="rectangle"下必须加android:useLevel="false",否则系统当它是 progress drawable 处理,跳过虚线渲染 - 只设
dashWidth不设dashGap,或反过来,会导致实线(gap=0)或不可见(width=0),两者必须成对出现
dashWidth 和 dashGap 的单位和比例关系
它们都用 dp,但实际渲染受容器尺寸和缩放影响。关键不是绝对值,而是两者的比值决定“虚实节奏”:比如 dashWidth="2dp" + dashGap="6dp" 得到 1:3 的短线+长空,而 dashWidth="4dp" + dashGap="4dp" 是等长虚实交替。
- 小屏设备上建议用
1dp/3dp起步,避免虚线糊成一片 - 若用在
TextView的 background 上,文字缩放会间接影响虚线密度,优先测试不同 fontScale 场景 - 不要混用
sp——系统不支持,会静默回退为 0
XML 虚线在 Android 4.4 以下不显示?
是的,dashWidth 和 dashGap 属性从 API 21(Android 5.0)才完整支持;4.4 及之前版本会忽略这两个属性,只画实线。这不是 bug,是原生限制。
- 兼容方案只有两个:用
LayerDrawable拼接多个shape模拟虚线,或改用自定义Drawable类重写draw() - 如果项目最低支持 API 21+,可放心用,无需降级处理
- 注意 build.gradle 中
compileSdk≥ 21 不代表运行时支持——得看minSdk,4.4 对应 API 19
为什么虚线总偏移或截断?
因为 stroke 默认居中绘制,而 rectangle 的宽高包含 stroke 宽度。如果你设了 android:width="1dp" 又加 android:strokeWidth="2dp",实际线条会溢出边界,导致虚线首尾被裁掉。
- 对 line 形状:确保父容器有足够 padding,或用
android:paddingStart预留空间 - 对 rectangle 形状:计算时把
strokeWidth算进总尺寸,例如要显示完整一周期(dash + gap = 8dp),view 的最小高度/宽度至少为strokeWidth + 8dp - 使用
android:dither="true"可缓解高缩放下的锯齿,但无法修复裁剪——裁剪是布局阶段的事










