radial渐变必须指定带单位的gradientradius(如150dp),否则android 8.0+失效;centerx/centery须写为"50%"或0.5,android:angle和tilemode无效,centercolor仅api 21+支持。

radial 渐变必须指定 gradientRadius,否则在 Android 8.0+ 上直接失效
Android 系统对 radial 类型的渐变做了严格校验:如果没显式设置 gradientRadius,即使写了 centerX 和 centerY,渲染也会退化为纯色(通常是第一个 color),尤其在 API 26+ 设备上几乎必现。
这是因为系统需要明确知道“径向范围多大”,不能靠父容器尺寸反推——它压根不这么算。
实操建议:
-
gradientRadius值必须是带单位的尺寸,比如150dp或200px;写成150(无单位)会被忽略 - 推荐用
dp,避免在高密度屏上缩得太小;若需铺满容器,得配合android:useLevel="false"并手动计算半径(见下一条) - 如果想让径向刚好覆盖整个 View,
gradientRadius至少设为:sqrt(width² + height²) / 2的 dp 值(按实际 layout 尺寸估算)
centerX / centerY 是相对百分比,不是像素值
这两个属性默认单位是百分比(50% 表示中心),不是 px/dp。写成 centerX="100" ≠ 右边缘,而是“100% 宽度位置”,即超出 View 范围——此时渐变中心落在 View 右侧外面,视觉上会偏左、甚至只看到一个色块。
常见错误现象:
-
centerX="0"→ 渐变中心在最左边缘,左侧颜色浓,右侧快速衰减 -
centerX="200"→ 中心在 View 右侧一倍宽的位置,View 内几乎全是起始色 - 忘记加
%符号(如centerX="50")→ 被当整数解析,等效于50px,在不同屏幕会错位
正确写法只有两种:centerX="50%"(推荐)或 centerX="0.5"(小数形式,也合法)
radial 渐变不支持 android:type="sweep" 混用,也不响应 android:angle
XML shape 中的 radial 是固定从中心向外发散的球面投影,没有方向概念。所以:
-
android:angle对type="radial"完全无效,写了也不起作用 - 不能和
sweep或linear混写在一个<gradient></gradient>标签里——系统只认第一个type值,其余被丢弃 - 如果需要“带角度的辐射效果”,只能换方案:用
layer-list叠加多个 radial,或改用Shader在代码里动态绘制
顺带一提:android:useLevel="true"(默认值)会让 radial 渐变受 LevelListDrawable 控制,普通 background 场景应设为 false,否则可能不显示
低版本兼容性坑:API 21 以下不支持 android:centerColor
如果你想在径向渐变中实现三色过渡(中心色 + 边缘色 + 过渡色),会用到 android:centerColor。但它只在 API 21(Lollipop)及以上生效。在 4.4(API 19)设备上,这个属性直接被忽略,退化为双色 radial(android:startColor 和 android:endColor)。
应对建议:
- 如果必须兼容旧版本,放弃
centerColor,改用两个嵌套的shape:外层 radial(start→end),内层小 circle(centerColor),用layer-list叠加 - 检查 build.gradle 的
minSdkVersion,若 ≥21,可放心用;否则要加 fallback drawable -
android:tileMode对 radial 无效,设了也没用,别白费劲
真正难调的从来不是写法,而是 radius 和 center 的组合在不同屏幕密度、不同 View 尺寸下的表现差异——同一组值,在模拟器上好看,到了真机上可能偏得离谱。动手前先在目标机型上测两版。










