radial gradient 的 centery 是 0~1 的相对比例值,非像素单位;必须配合 gradientradius 使用,且仅 api 21+ 支持,低版本会忽略并居中。

radial gradient 的 centerY 是相对值,不是像素
Android XML 径向渐变里 centerY 必须是 0~1 范围内的浮点数,表示占整个 drawable 高度的比例。写成 centerY="100" 或 centerY="50dp" 都无效,系统会静默忽略,渐变中心默认回退到 0.5(垂直居中)。
- 正确写法:
centerY="0.25"表示在顶部往下 1/4 处 - 常见错误:复制线性渐变的写法,误用 dp/px 单位或绝对数值
- 如果设为负数或 >1,行为未定义,部分旧版本可能崩溃,新版本通常截断为 0 或 1
radial 渐变必须配 gradientRadius,否则 centerY 不生效
XML 中只要漏了 gradientRadius,整个 radial 就退化成默认的线性渐变(哪怕写了 type="radial"),此时 centerY 完全被无视——你调半天位置都没用,因为根本没走径向逻辑。
-
gradientRadius也必须是尺寸单位(dp或px),不能是比例 - 推荐用
gradientRadius="150dp"这类明确值;用android:gradientRadius="150"(无单位)在某些 API 版本会解析失败 - 若 drawable 尺寸动态变化(比如作为 Button 背景),固定
gradientRadius可能导致渐变溢出或过小,这时得换代码层生成RadialGradient
API 21+ 才支持 centerX/centerY 独立控制
低于 Android 5.0(API 21)的设备,XML 中设置 centerX 或 centerY 会被直接忽略,渐变中心永远锁定在 (0.5, 0.5)。这不是 bug,是原生限制。
- 检查方式:在 API 19 模拟器上运行,看效果是否和预想不一致
- 兼容方案只有两个:放弃 XML 径向渐变,改用
ShapeDrawable+RadialGradient在代码里构造;或者接受老设备统一居中 - 别试图用
android:attr/或自定义属性绕过,系统底层没实现
drawable 尺寸不确定时,centerY 的实际位置很难预测
XML shape 是按最终渲染尺寸归一化坐标的,但很多场景下 drawable 尺寸由 View 决定(比如 ImageView 的 wrap_content + 图片尺寸、Button 的文字高度等)。这时候你写的 centerY="0.3",最终落在屏幕哪个 Y 像素,取决于 runtime 的测量结果。
- 调试技巧:给父容器加
background="#ff00ff",把 shape drawable 放进去,肉眼观察渐变中心偏移是否符合预期 - 如果 View 高度经常变化(如软键盘弹出),XML 方案基本不可控,必须切到
onDraw()里用Canvas.translate()+RadialGradient - 注意
android:useLevel="true"会影响 shape 渲染逻辑,开启后centerY行为可能异常










