Flutter中如何实现文本颜色从左到右填充的动画效果
Flutter Text组件从左到右颜色填充动画实现方案
通过ShaderMask配合线性渐变、动画控制器即可实现该效果,核心逻辑是通过动画值控制渐变的停止位,实现颜色填充范围从左向右逐步扩展的效果。
实现步骤
- 自定义Stateful组件,混入
SingleTickerProviderStateMixin,初始化动画控制器和补间动画对象 - 使用
ShaderMask包裹目标Text组件,将线性渐变的停止位与动画值绑定 - 根据业务需求触发动画的正向/反向/循环执行
完整示例代码
import 'package:flutter/material.dart'; class GradientFillText extends StatefulWidget { /// 要展示的文字内容 final String text; /// 文字样式 final TextStyle style; /// 填充色(动画最终要展示的颜色) final Color fillColor; /// 初始背景色(文字未填充部分的颜色) final Color placeholderColor; /// 动画执行时长 final Duration duration; const GradientFillText({ super.key, required this.text, required this.style, required this.fillColor, required this.placeholderColor, this.duration = const Duration(milliseconds: 1500), }); @override State<GradientFillText> createState() => _GradientFillTextState(); } class _GradientFillTextState extends State<GradientFillText> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<double> _fillProgress; @override void initState() { super.initState(); _controller = AnimationController(vsync: this, duration: widget.duration); _fillProgress = Tween<double>(begin: 0, end: 1).animate( CurvedAnimation(parent: _controller, curve: Curves.easeInOut) ); // 组件加载完成后自动播放动画,不需要可注释 _controller.forward(); } @override void dispose() { _controller.dispose(); super.dispose(); } /// 手动触发动画执行 void runAnimation() { _controller.reset(); _controller.forward(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _fillProgress, builder: (context, child) { return ShaderMask( blendMode: BlendMode.srcATop, shaderCallback: (textBounds) { return LinearGradient( colors: [widget.fillColor, widget.placeholderColor], stops: [_fillProgress.value, _fillProgress.value], begin: Alignment.centerLeft, end: Alignment.centerRight, ).createShader(textBounds); }, child: Text(widget.text, style: widget.style), ); }, ); } } // 调用示例 // GradientFillText( // text: "Flutter Animation", // style: TextStyle(fontSize: 48, fontWeight: FontWeight.bold), // fillColor: Colors.blueAccent, // placeholderColor: Colors.grey.shade300, // duration: Duration(seconds: 2), // )
自定义调整方式
- 需要循环来回填充的场景,可将
_controller.forward()替换为_controller.repeat(reverse: true) - 调整
CurvedAnimation的curve参数可以修改动画的运动速率曲线,实现加速、弹跳等效果 - 文字本身需要带透明底色的场景,可将
blendMode改为BlendMode.srcIn
内容的提问来源于stack exchange,提问作者Long Hoàng
相关产品推荐
相关产品推荐

