Android 界面中的背景除了使用纯色和位图,还可以通过 shape 可绘制对象来定义更灵活的图形。当需要按钮、卡片或进度条呈现从一种颜色平滑过渡到另一种颜色的效果时,<gradient> 子标签就派上了用场。它允许开发者在 XML 中声明渐变参数,系统在运行时自动渲染,不占用额外图片内存,也方便适配不同屏幕密度。

与直接使用 PNG 渐变图相比,shape gradient 的优势在于可维护性和体积。颜色变化可以直接修改 XML 文件中的十六进制值,不需要重新切图;同时渐变的平滑度由系统矢量渲染保证,不会因为缩放出现锯齿。不过需要注意的是,gradient 标签必须作为 shape 根节点的子元素出现,并且 shape 需要指定为 rectangle、oval 或 line 等类型才能正确绘制。
gradient 基础属性与三种渐变类型
在 shape 中使用渐变的语法结构如下:先定义根节点 <shape>,然后在内部添加 <gradient> 子标签。该子标签支持多个属性,其中 android:type 决定了渐变的基本形态,可取值为 linear、radial 和 sweep。如果不写 type,默认就是 linear 线性渐变。
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:type="linear"
android:startColor="#FF6B6B"
android:endColor="#4ECDC4" />
</shape>
上面的代码定义了一个从珊瑚红过渡到薄荷绿的矩形背景。系统会自动从 startColor 到 endColor 进行插值计算,中间不指定 centerColor 时会均匀混合两种颜色。需要注意 startColor 是必须指定的颜色,而 endColor 如果不写,默认会和 startColor 相同,导致渐变不可见。
三种渐变类型的区别很明显:linear 是沿一条直线方向渐变,方向由 android:angle 控制;radial 是从一个中心点向外辐射渐变,需要 android:gradientRadius 指定半径;sweep 是绕着中心点按角度扫描渐变,类似雷达扫描的色盘效果。不同类型的适用场景不同,线性渐变适合按钮背景和分隔线,径向渐变适合高光球体或水波纹,扫描渐变则常见于仪表盘和圆形进度指示器。
线性渐变的 angle 属性与颜色分布
当 android:type 设置为 linear 时,android:angle 属性决定渐变方向。该属性接受整数值,必须是 45 的倍数,包括 0、45、90、135、180、225、270、315。角度以度为单位,默认值是 0,表示从左到右渐变。需要注意的是角度并非屏幕坐标系的绝对方向,而是相对于形状自身的坐标,当形状被旋转或拉伸时方向会相应变化。
具体的角度对应关系为:0 度是从左到右,此时 startColor 在左侧,endColor 在右侧;90 度是从下到上,startColor 在底部,endColor 在顶部;180 度是从右到左;270 度是从上到下。如果想实现常见的从上到下渐变,需要写成 android:angle="270",而不是 90,这一点很多开发者容易弄反。
<gradient
android:type="linear"
android:angle="270"
android:startColor="#FF512F"
android:centerColor="#DD2476"
android:endColor="#FF512F" />
中间色 android:centerColor 并不是渐变的中点,而是一个额外的颜色停靠点。系统会在 startColor 与 centerColor 之间、centerColor 与 endColor 之间分别进行线性插值,因此 centerColor 的实际位置固定在整段渐变的 50% 处。如果希望中间色出现在其他位置,比如 30% 处,XML 属性无法直接实现,需要借助代码动态创建 GradientDrawable 并设置颜色数组和位置数组。在纯 XML 场景下,centerColor 只能让三色渐变更生动,但位置固定不可调。
还要注意 angle 属性只对 linear 类型有效,对 radial 和 sweep 类型不起作用。如果给 radial 渐变写了 angle,系统会直接忽略,不会报错但也不会产生预期效果。
径向渐变与扫描渐变的特殊配置
径向渐变 (radial) 从中心点向外扩散颜色,默认中心点位于形状的中心。可以通过 android:centerX 和 android:centerY 调整中心点坐标,取值范围是 0 到 1 的小数,表示相对于形状宽度和高度的比例。例如 centerX="0.3" 表示中心点位于水平方向 30% 的位置。如果想让径向渐变的光源偏移到左上角,可以设置 android:centerX="0.2" 和 android:centerY="0.2"。
<gradient
android:type="radial"
android:startColor="#FFFDEB71"
android:centerColor="#FFFF8C00"
android:endColor="#FFFF0080"
android:gradientRadius="120dp"
android:centerX="0.5"
android:centerY="0.5" />
径向渐变的半径由 android:gradientRadius 指定,单位为 dp 或 px。如果不指定该属性,系统会使用形状对角线的一半作为默认半径,但不同 API 版本下默认行为可能不一致,因此建议显式设置。当半径小于形状尺寸时,超出半径的区域会填充 endColor;当半径大于形状尺寸时,渐变会在形状边缘被裁剪。实际使用时通常让半径略大于形状的最远距离,以保证渐变完整。
扫描渐变 (sweep) 的行为最为特殊,它不沿直线或半径方向,而是围绕中心点以角度进行渐变。startColor 出现在 0 度位置,endColor 出现在 360 度位置,颜色沿顺时针方向过渡。扫描渐变的中心点同样可以用 android:centerX 和 android:centerY 调整,但没有半径属性,渐变覆盖整个形状。这种类型适合制作圆形色盘、风扇叶片或雷达扫描效果。
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<gradient
android:type="sweep"
android:startColor="#FF00E5FF"
android:endColor="#FFAA00FF" />
<size
android:width="150dp"
android:height="150dp" />
</shape>
需要注意扫描渐变没有 centerColor 属性,如果写了也会被忽略。它只接受 startColor 和 endColor。此外,由于扫描渐变的颜色过渡不连续(在 0 度与 360 度交界处会突然跳变),视觉上会产生明显的分界线,如果希望平滑过渡,需要在 startColor 和 endColor 使用相同的颜色,或者改用其他渐变类型。
渐变与 corners、stroke、padding 的组合应用
单独的渐变背景通常不够精致,实际项目中往往需要结合圆角 (corners)、边框 (stroke) 和内边距 (padding) 来完善视觉效果。例如制作一个渐变按钮背景,可以同时设置圆角半径、边框颜色和渐变方向,使按钮在点击和默认状态下都有良好的观感。
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:type="linear"
android:angle="45"
android:startColor="#FF667EEA"
android:endColor="#FF764BA2" />
<corners android:radius="25dp" />
<stroke
android:width="1dp"
android:color="#80FFFFFF" />
<padding
android:left="16dp"
android:top="10dp"
android:right="16dp"
android:bottom="10dp" />
</shape>
这里将线性渐变角度设置为 45 度,使颜色沿对角线从左上到右下变化。圆角 25dp 让背景呈现圆角矩形,接近现代 UI 风格。白色半透明边框提供了微妙的层次感,而 padding 则确保按钮文字不会紧贴边缘。需要注意的是 padding 属性作用于 View 的内容区域,并不影响 shape 的绘制范围,如果 View 本身没有设置 padding,可以直接使用 shape 的 padding 来预留空间。
当渐变与 stroke 同时使用时,stroke 的颜色不受渐变影响,始终保持指定的纯色。如果想让边框也呈现渐变效果,需要叠加多个 drawable 或使用 layer-list 实现,但大多数情况下纯色边框已经足够。另一个常见组合是给圆形头像添加径向渐变作为背景光晕,同时用 stroke 勾勒边缘,使头像看起来像镶嵌在彩色光环中。
常见问题与兼容性注意事项
一个常见的误区是认为 android:angle 可以取任意角度值,例如 30 度或 60 度。实际上 angle 必须是 45 的整数倍,传入其他值会被系统取整到最近的 45 倍数,导致渐变方向与预期不符。如果确实需要非 45 倍数角度的渐变,必须使用代码创建 GradientDrawable,通过 setOrientation 配合自定义矩阵来实现更精细的角度控制。
兼容性方面,shape gradient 从 Android API 1 就支持,因此不存在版本限制。但不同厂商的 ROM 在渲染径向渐变默认半径时可能存在差异,建议始终显式设置 android:gradientRadius。另外,在 Android 5.0 及更高版本中,如果 View 使用了 Ripple 效果,渐变背景可能会与 Ripple 遮罩叠加,使颜色看起来偏暗,可以通过设置 android:drawable 的 alpha 属性或调整颜色值来改善。
性能上,shape 渐变由系统使用 Skia 引擎绘制,效率远高于逐像素处理位图,在列表滚动等场景下也不会造成明显卡顿。但如果一个布局中存在大量复杂的 sweep 渐变,且每个 View 尺寸较大,仍然可能增加 GPU 负载。对于列表项中的渐变背景,建议复用相同的 drawable 资源而不是为每个 item 动态创建新的 GradientDrawable,这样可以利用系统缓存减少对象创建开销。
总结来说,Android 的 shape gradient 提供了一套轻量、灵活且易维护的渐变背景方案。掌握线性、径向和扫描三种类型的属性搭配,能够在不引入额外图片资源的前提下,构建出丰富的界面视觉效果。在实际开发中多尝试不同角度、中心点位置和颜色组合,就能避免常见的配置错误,让渐变真正为界面增色。
Android shape gradient渐变色XML背景修改时间:2026-08-21 09:39:13