thicknessratio = innerdiameter / outerdiameter,数值越小环越粗;必须设 uselevel="false" 才生效;与 innerradiusratio 互斥,不可共存;xml 中为比例值,非像素,且无法运行时修改。

shape ring 的 thicknessRatio 到底怎么算?
它不是“圆环厚度占整个图形宽度的比例”,而是“内圆直径与外圆直径的比值”。换句话说:thicknessRatio = innerDiameter / outerDiameter。所以数值越小,圆环越粗;越大,圆环越细(甚至趋近于一个实心圆)。常见误用是把它当成 0–1 的“厚度百分比”,结果设成 0.5 却得到一根极细的线。
XML 中写 thicknessRatio 必须配 useLevel="false"
Android 的 shape 默认是 LevelListDrawable 类型,而 thicknessRatio 只在 useLevel="false" 时生效。不加这句,无论你怎么调这个值,圆环看起来都一样——因为系统压根没读它。
正确写法示例:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:useLevel="false"
android:innerRadiusRatio="2"
android:thicknessRatio="3">
<solid android:color="#FF6B6B"/>
</shape>
innerRadiusRatio 和 thicknessRatio 别混用
这两个参数控制的是同一环形区域,但逻辑不同、互斥使用:
-
innerRadiusRatio:按“外圆半径 / 比值”算内圆半径,比如innerRadiusRatio="2"→ 内圆半径 = 外圆半径 ÷ 2 -
thicknessRatio:按“内圆直径 / 外圆直径”算比例,比如thicknessRatio="4"→ 内圆直径 = 外圆直径 ÷ 4 → 内圆半径 = 外圆半径 ÷ 4
两者不能同时设,否则后者会被忽略;官方文档也明确说它们是互斥属性。实际项目中建议只选一个,优先用 thicknessRatio,语义更贴近“环形厚度控制”。
动态修改 ring 厚度?别碰 XML,改代码
XML 定义的 shape 是静态资源,thicknessRatio 无法运行时修改。想让圆环粗细随状态变化(比如 loading 动画变细),得用 GradientDrawable 或自定义 Drawable:
例如,在 Kotlin 中重设环形尺寸:
val drawable = gradientDrawable as GradientDrawable drawable.setShape(GradientDrawable.RING) drawable.setStroke(width, color) // width 是像素值,直接控制环宽
注意:setStroke() 的 width 是绝对像素,和 XML 里的比例逻辑完全不同;而且必须确保 gradientDrawable 是从 ShapeDrawable 或代码创建而来,不能是 @drawable/xxx 这种编译好的 XML 资源。
最常被忽略的一点:XML 中的 thicknessRatio 是无单位比例,但它的计算依赖于最终绘制尺寸——如果父容器拉伸了 drawable,环的实际像素厚度会跟着缩放,不是固定值。要精确控制像素级粗细,XML 就不适合。










