如何在Flutter中创建带闪光效果和百分比的可定制动画进度条?
可复用的Flutter动画进度条组件(带闪光效果)
当然有可复用的实现方式,直接封装成一个独立的StatefulWidget就能满足你所有需求,下面是完整的可复用代码,附带详细的使用说明:
完整组件代码
import 'package:flutter/material.dart'; class AnimatedProgressBar extends StatefulWidget { final double progress; // 范围 0.0 - 1.0 final Color backgroundColor; final Color progressColor; final bool showShimmer; final Duration animationDuration; final TextStyle? percentageTextStyle; const AnimatedProgressBar({ super.key, required this.progress, this.backgroundColor = Colors.grey[200]!, this.progressColor = Colors.blue, this.showShimmer = false, this.animationDuration = const Duration(milliseconds: 500), this.percentageTextStyle, }) : assert(progress >= 0.0 && progress <= 1.0, "进度值必须在0-1之间"); @override State<AnimatedProgressBar> createState() => _AnimatedProgressBarState(); } class _AnimatedProgressBarState extends State<AnimatedProgressBar> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<double> _progressAnimation; @override void initState() { super.initState(); _controller = AnimationController( duration: widget.animationDuration, vsync: this, ); // 初始化动画,从0开始到初始进度值 _progressAnimation = Tween<double>(begin: 0.0, end: widget.progress).animate( CurvedAnimation(parent: _controller, curve: Curves.easeInOut), ); _controller.forward(); } @override void didUpdateWidget(covariant AnimatedProgressBar oldWidget) { super.didUpdateWidget(oldWidget); // 进度变化时,重新设置动画并播放 if (oldWidget.progress != widget.progress) { _progressAnimation = Tween<double>(begin: _progressAnimation.value, end: widget.progress).animate( CurvedAnimation(parent: _controller, curve: Curves.easeInOut), ); _controller.reset(); _controller.forward(); } } @override void dispose() { // 及时销毁控制器,避免内存泄漏 _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: [ // 顶部百分比文本 Text( '${(_progressAnimation.value * 100).round()}%', style: widget.percentageTextStyle ?? TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: widget.progressColor, ), ), const SizedBox(height: 8), // 进度条容器 Container( height: 12, width: double.infinity, decoration: BoxDecoration( color: widget.backgroundColor, borderRadius: BorderRadius.circular(6), ), clipBehavior: Clip.hardEdge, child: AnimatedBuilder( animation: _progressAnimation, builder: (context, child) { Widget progressBar = FractionallySizedBox( widthFactor: _progressAnimation.value, child: Container(color: widget.progressColor), ); // 如果开启闪光效果,用ShaderMask添加渐变闪光 if (widget.showShimmer) { progressBar = ShaderMask( shaderCallback: (bounds) => LinearGradient( colors: [ widget.progressColor, Colors.white.withOpacity(0.5), widget.progressColor, ], stops: const [0.0, 0.5, 1.0], begin: Alignment.centerLeft, end: Alignment.centerRight, ).createShader(bounds), blendMode: BlendMode.srcATop, child: progressBar, ); } return progressBar; }, ), ), ], ); } }
使用示例
在你的页面中直接调用这个组件即可,下面是一个简单的演示:
class ProgressDemoPage extends StatefulWidget { const ProgressDemoPage({super.key}); @override State<ProgressDemoPage> createState() => _ProgressDemoPageState(); } class _ProgressDemoPageState extends State<ProgressDemoPage> { double _currentProgress = 0.3; void _updateProgress() { setState(() { _currentProgress = (_currentProgress + 0.2).clamp(0.0, 1.0); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('进度条演示')), body: Padding( padding: const EdgeInsets.all(20.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // 带闪光效果的进度条 AnimatedProgressBar( progress: _currentProgress, showShimmer: true, progressColor: Colors.green, backgroundColor: Colors.grey[300]!, ), const SizedBox(height: 40), // 不带闪光效果的进度条 AnimatedProgressBar( progress: _currentProgress, showShimmer: false, progressColor: Colors.orange, percentageTextStyle: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.orange, ), ), const SizedBox(height: 40), ElevatedButton( onPressed: _updateProgress, child: const Text('更新进度'), ), ], ), ), ); } }
核心特性说明
- 平滑动画过渡:每次进度更新时,会从当前进度值平滑过渡到新值,动画曲线和时长都可配置
- 可选闪光效果:通过
showShimmer参数一键开关,用ShaderMask实现高效的渐变闪光效果 - 高度自定义:支持配置背景色、进度色、百分比文本样式、动画时长等
- 内存安全:正确实现了
dispose方法销毁动画控制器,避免内存泄漏
内容的提问来源于stack exchange,提问作者waka
相关产品推荐
相关产品推荐

