android:angle必须是45的倍数(0/45/90/135/180/225/270/315),否则静默修正为最近合法值;radial渐变需同时指定centerx、centery和gradientradius(单位px,非dp);centercolor仅对linear和radial有效,sweep中无效。

android:angle 必须是 45 的倍数,否则会被忽略
XML 中 android:angle 看似支持任意整数,但实际只接受 0、45、90、135、180、225、270、315 这 8 个值——这是 Android 渲染引擎硬编码的限制。设成 30 或 100 不会报错,但效果等同于最近的合法值(比如 30 → 0,100 → 90)。
常见错误现象:改了 angle 却没看到方向变化,怀疑是缓存或代码没生效,其实只是角度非法被静默修正了。
-
0:从左到右(⚠️注意:不是“上到下”,很多文档写反了) -
90:从上到下(即 startColor 在顶部,endColor 在底部) -
180:从右到左 -
270:从下到上
radial gradient 必须同时指定 centerX、centerY 和 gradientRadius
径向渐变不填全这三个属性,就根本不会显示为放射状——它会退化成纯色(通常是 startColor),而不是报错或警告。
原因在于:gradientRadius 单位是像素(px),不是 dp;且它没有默认值,不写就是 0,半径为 0 的圆自然不可见。
-
android:centerX="0.5"和android:centerY="0.5"表示中心在 View 宽高各 50% 处(相对坐标,范围 0–1) -
android:gradientRadius="300"要根据目标 View 尺寸估算:太小(如 50)只在中间一小块渐变;太大(如 2000)可能超出屏幕边界,但 Android 会裁剪,不影响渲染 - 别用 dp 单位写
gradientRadius,XML 解析器不认"300dp",只接受纯数字
三色渐变靠 centerColor,但它只对 linear 和 radial 生效
android:centerColor 是实现平滑三段过渡的关键,但它的行为高度依赖 android:type:
- 线性渐变中,颜色顺序严格按
startColor → centerColor → endColor沿直线分布 - 径向渐变中,
startColor在圆心,centerColor出现在半径中途,endColor在边缘 - 扫描渐变(
sweep)**完全忽略**centerColor,写了也没用 - 如果只写
startColor和endColor,系统自动做两色插值;加了centerColor后,插值路径变成两段独立线性插值,视觉更丰富
典型误用:在 sweep 渐变里加 centerColor 以为能增强层次感,结果毫无变化。
GradientDrawable 代码创建比 XML 更灵活,但 cornerRadius 需手动设
用 Kotlin 动态创建渐变时,GradientDrawable 构造函数不带圆角,必须额外调用 cornerRadius 属性,否则即使 View 本身有圆角背景,渐变也会溢出成直角。
val gradient = GradientDrawable(
GradientDrawable.Orientation.LEFT_RIGHT,
intArrayOf(Color.RED, Color.BLUE)
)
gradient.cornerRadius = 12f // 单位是 float,单位是 px,不是 dp
view.background = gradient对比 XML:<shape></shape> 可以直接在同一个文件里配 <corners></corners> 和 <gradient></gradient>,天然协同;而代码方式需手动同步圆角值,容易遗漏或单位换算错误。
另外注意:GradientDrawable.Orientation 枚举值和 XML 的 angle 不是一一对应关系,比如 LEFT_RIGHT ≈ angle="0",TOP_BOTTOM ≈ angle="90",但没法精确表达 45 这样的斜向——这时候还是得回 XML 或用 setOrientation() + 自定义矩阵。
XML 里看似简单的 <gradient></gradient>,实则每个属性都带着平台级约束和隐式规则。最常被忽略的是 gradientRadius 的单位陷阱、angle 的离散取值,以及 centerColor 的类型有效性。写完别急着跑,先检查这三项是否合规。










