radial渐变的centerX和centerY是0.0–1.0范围内的相对值,非像素单位;必须同时设置,且需配合gradientRadius(基于控件最短边的比例)才生效;无android:前缀写法兼容所有API版本。

radial 渐变的 centerX 和 centerY 是相对值,不是像素
Android 的 shape XML 中,radial 渐变默认以控件中心为起点,但你不能直接填 50dp 或 100px。所有坐标都是 0.0–1.0 范围内的比例值:centerX="0.5" 表示水平居中,centerY="0.3" 表示从顶部往下 30% 的位置。
常见错误是照着 Photoshop 坐标抄数字,结果渐变完全偏出可视区;或者误以为单位是 dp,填了 centerX="100",XML 解析时不会报错,但效果等同于 centerX="1.0"(因为超出 1.0 会被截断)。
-
centerX和centerY必须同时设置,缺一不可 - 如果只设一个,系统会用默认值 0.5,但行为不稳定,某些 Android 版本可能忽略整个
gradient标签 - 值支持小数,比如
centerX="0.25"、centerY="0.75",也支持科学计数法(不推荐,可读性差)
radial 渐变必须配 gradientRadius,否则中心点无效
只设 centerX/centerY 不起作用——Android 会退化成默认居中径向渐变。真正控制“影响范围”的是 gradientRadius,它也是相对值,单位是“控件最短边长度的比例”。
例如:一个宽 400dp、高 200dp 的 View,最短边是 200dp;若设 gradientRadius="1.0",半径就是 200dp;设 gradientRadius="0.5",半径就是 100dp。这个半径决定了颜色从中心扩散到哪一“圈”结束。
-
gradientRadius必须大于 0,设成 0 或负数会导致渐变消失(部分机型显示纯色) - 超过 1.0 是允许的,比如
gradientRadius="1.5",表示半径为最短边的 1.5 倍,能覆盖更大区域甚至溢出 - 没有
gradientRadius属性时,系统不会 fallback 到默认值,而是直接忽略 radial 模式,降级为线性渐变(仅在旧版本如 API 16 上观察到)
API 21+ 才支持 android:centerX 等命名空间前缀写法
如果你在 res/drawable/xxx.xml 里写了 android:centerX="0.3",却在 Android 4.4(API 19)设备上发现渐变始终居中,问题就在这儿:带 android: 前缀的属性在 API 21 以下被完全忽略,系统只认无前缀的 centerX。
但反过来,如果你用的是老式写法(无命名空间),在新项目里又开了 tools:targetApi="21" 或使用了 AndroidX 的编译配置,部分构建流程可能警告“缺少命名空间”,其实不影响运行——只要没加 android: 就兼容所有 API。
- 安全写法:统一用无前缀形式,即
centerX、centerY、gradientRadius - 不要混用,比如一半加
android:一半不加,会导致低版本解析失败或静默丢弃 - Gradle 插件 4.2+ 对这类写法更严格,可能在 build 时报
Attribute is not bound,但只是 lint 提示,不影响打包
center 偏移后,gradientRadius 计算基准仍是原始控件尺寸
这是最容易被忽略的细节:哪怕你把 centerX="0.8" 把中心点拉到右侧,gradientRadius="1.0" 的半径依然按“控件最短边长度”算,而不是按到右边缘的距离。也就是说,中心偏右 + 大半径 ≠ 右侧更亮,它只是把整个圆形渐变“平移”过去,形状不变。
想实现非对称强调效果(比如右下角高亮),不能只调 center,得配合 type="sweep" 或拆成多个 layer-list,或者改用 Shader 代码绘制。
- 测试时务必在不同屏幕宽高比的设备上预览,比如全面屏 vs 平板,centerY=0.5 在窄屏上可能刚好,但在超长屏上会显得太高
- 没有 runtime 动态修改
centerX的标准方式,XML 定义后就固定了;需要动态偏移,得用GradientDrawable代码创建并调用setGradientCenter() - 所有 center 相关计算都不受 View 的
padding或margin影响,只基于 drawable 自身绘制边界










