在 Flutter 中,渐变(Gradient) 广泛用于背景、按钮、文字、边框、进度条等场景,能让 UI 更生动、更具层次感。Flutter 提供的渐变 API 功能强大,同时保持极高的性能表现。本文将从基础到进阶,带大家全面掌握 Flutter 中渐变的使用。
✨ 1. 什么是 Gradient?
Gradient 是 Flutter 中用于绘制颜色渐变的抽象类,其常见子类及说明如下表所示:
| 类型 | 类名 | 说明 |
|---|---|---|
| 线性渐变 | LinearGradient | 从 A 点到 B 点的颜色渐变 |
| 径向渐变 | RadialGradient | 以圆形扩散的渐变 |
| 扫射渐变 | SweepGradient | 以中心为轴按角度渐变(饼图、圆形进度条常用) |
| 渐变文本/图标 | ShaderMask | 用渐变给任意控件上色 |
渐变通常用于 BoxDecoration 中,也可应用到 Paint、CustomPainter、ShaderMask 等更底层的绘制场景。
🎨 2. LinearGradient(线性渐变)
线性渐变是最常用的渐变类型,以下是从左到右的线性渐变背景示例:
dart
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
),
)
常见方向(速记)
| begin | end | 含义 |
|---|---|---|
| topCenter | bottomCenter | 上 → 下 |
| centerLeft | centerRight | 左 → 右 |
| topLeft | bottomRight | 左上 → 右下 |
🎯 控制颜色过渡的 stops
通过 stops 参数可精准控制颜色过渡的位置,示例如下:
dart
LinearGradient(
colors: [Colors.red, Colors.green, Colors.blue],
stops: [0.2, 0.5, 1.0], // 对应颜色在渐变中的位置比例
)
🌌 3. RadialGradient(径向渐变)
径向渐变以圆形向外扩散,适合制作背景光、聚焦效果,示例如下:
dart
Container(
decoration: BoxDecoration(
gradient: RadialGradient(
colors: [Colors.yellow, Colors.orange, Colors.deepOrange],
radius: 0.85, // 渐变半径(0-1,1 表示充满容器)
),
),
)
🎯 控制中心点位置
通过 center 参数可调整径向渐变的中心点,示例如下:
dart
RadialGradient(
colors: [Colors.yellow, Colors.orange],
center: const Alignment(-0.5, -0.5), // 偏左上(取值范围 -1 到 1)
radius: 0.85,
)
🔄 4. SweepGradient(扫射渐变)
扫射渐变以角度方向渐变,常用于圆形进度条、饼图背景等场景,示例如下:
dart
Container(
decoration: BoxDecoration(
gradient: SweepGradient(
colors: [Colors.blue, Colors.green, Colors.yellow, Colors.blue],
),
),
)
控制开始结束的角度
通过 startAngle 和 endAngle 参数可控制渐变的角度范围(单位:弧度),示例如下:
dart
SweepGradient(
startAngle: 0.0, // 起始角度(0 对应右侧水平方向)
endAngle: 3.14, // 结束角度(3.14 即 π,对应左侧水平方向)
colors: [Colors.red, Colors.yellow],
)
🅰️ 5. 将渐变用于文字:ShaderMask / Paint
⭐ 渐变文字(最常见用法)
通过 TextStyle 的 foreground 参数结合 Paint 实现渐变文字,示例如下:
dart
Text(
'Flutter Gradient',
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
foreground: Paint()
..shader = LinearGradient(
colors: [Colors.blue, Colors.purple],
).createShader(Rect.fromLTWH(0, 0, 200, 70)), // 文字所在矩形区域
),
)
⭐ 用 ShaderMask 给任意控件上色
ShaderMask 可给图标、图片等任意控件添加渐变效果,示例如下:
dart
ShaderMask(
shaderCallback: (bounds) { // bounds 为控件的尺寸范围
return LinearGradient(
colors: [Colors.blue, Colors.green],
).createShader(bounds);
},
child: Icon(Icons.star, size: 120, color: Colors.white), // 控件需设为白色才会显示渐变
)
🔲 6. 渐变边框(实战技巧)
Flutter 默认不支持渐变边框,可通过 Stack + ClipRRect 或「外层渐变容器 + 内层内容容器」的方式实现,示例如下:
dart
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple],
),
borderRadius: BorderRadius.circular(12), // 外层渐变容器圆角
),
padding: const EdgeInsets.all(2), // 外层渐变边框厚度(值越大边框越粗)
child: Container(
decoration: BoxDecoration(
color: Colors.white, // 内层内容容器背景色(与外层形成边框对比)
borderRadius: BorderRadius.circular(10), // 内层圆角需比外层小,避免露边
),
child: const Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text("渐变边框"),
),
),
)
🎛 7. 渐变按钮
通过 ElevatedButton 结合 Ink 组件可实现渐变按钮,示例如下:
dart
ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero, // 清除默认内边距,避免渐变被截断
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), // 按钮圆角
),
),
onPressed: () {}, // 按钮点击事件
child: Ink( // 用 Ink 实现水波纹效果与渐变结合
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.pink],
),
borderRadius: BorderRadius.circular(10),
),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 20),
child: const Text(
"Gradient Button",
style: TextStyle(color: Colors.white), // 按钮文字颜色
),
),
),
)
🎚 8. 自定义画布渐变(CustomPainter)
通过 CustomPainter 可实现更灵活的渐变绘制(如渐变圆环),核心是给 Paint 设置渐变 shader,示例如下:
dart
class GradientRingPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final rect = Rect.fromCenter(
center: Offset(size.width / 2, size.height / 2),
width: size.width,
height: size.height,
);
// 创建渐变 shader
final shader = SweepGradient(
colors: [Colors.green, Colors.red],
startAngle: 0.0,
endAngle: 6.28, // 2π,即完整的圆形
).createShader(rect);
// 配置画笔(绘制圆环)
final paint = Paint()
..shader = shader
..style = PaintingStyle.stroke // 描边模式(绘制圆环)
..strokeWidth = 10; // 圆环厚度
// 绘制圆形(实际显示为圆环)
canvas.drawCircle(Offset(size.width / 2, size.height / 2), size.width / 2 - 5, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
// 使用自定义 Painter
Container(
width: 200,
height: 200,
child: CustomPaint(painter: GradientRingPainter()),
)
📈 9. 性能提示(重要)
- Flutter 的渐变基于 GPU 加速,在常规使用场景下几乎不会成为性能瓶颈。
- 大量
ShaderMask组件叠加可能增加渲染开销,复杂页面需注意控制数量。 - 实现渐变动画时,建议使用
TweenAnimationBuilder或AnimatedContainer,避免直接使用AnimationController手动刷新,减少不必要的重绘。
🧪 10. 实战:渐变卡片组件(可直接复用)
以下是封装好的渐变卡片组件,支持传入自定义子组件,可直接在项目中复用:
dart
class GradientCard extends StatelessWidget {
final Widget child;
// 可选参数:自定义渐变颜色、圆角、内边距
final List<Color>? gradientColors;
final double? borderRadius;
final EdgeInsetsGeometry? padding;
const GradientCard({
super.key,
required this.child,
this.gradientColors,
this.borderRadius = 20.0,
this.padding = const EdgeInsets.all(16.0),
});
@override
Widget build(BuildContext context) {
return Container(
padding: padding,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: gradientColors ?? [ // 默认渐变颜色
const Color(0xFF4FACFE),
const Color(0xFF00F2FE),
],
),
borderRadius: BorderRadius.circular(borderRadius!),
boxShadow: [ // 可选:添加阴影增强立体感
BoxShadow(
color: Colors.black12,
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: child,
);
}
}
// 使用示例
GradientCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("渐变卡片标题", style: TextStyle(color: Colors.white, fontSize: 18)),
SizedBox(height: 8),
Text("这是渐变卡片的内容区域", style: TextStyle(color: Colors.white70)),
],
),
)
🏁 总结
Flutter 提供了强大且多样化的渐变支持,核心要点如下:
- LinearGradient:最常用,支持自定义方向和颜色过渡位置,适用于大多数背景场景。
- RadialGradient:以圆形扩散,适合制作光晕、聚焦等效果。
- SweepGradient:按角度渐变,是圆形进度条、饼图的常用方案。
- ShaderMask 与 Paint:突破容器限制,可给文字、图标等任意控件添加渐变。
- 结合
Stack、Ink、CustomPainter等组件,还能实现渐变边框、渐变按钮、自定义渐变图形等复杂效果。
掌握这些渐变技巧,能帮助大家轻松实现更专业、更具质感的 Flutter UI 效果。