Flutter:基于Row实现可控制的背景色进度条(支持动画效果更佳)
当然可行!而且实现带动画的进度条效果也很简单,这里提供两种贴合你需求的方案:
方案一:仅填充左右文本之间的空间(精准控制进度区域)
这种方案会让进度条只在左右文本的中间区域显示,完全贴合你原来的Row结构,不会覆盖文本:
import 'package:flutter/material.dart'; class ProgressRow extends StatefulWidget { const ProgressRow({super.key}); @override State<ProgressRow> createState() => _ProgressRowState(); } class _ProgressRowState extends State<ProgressRow> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<double> _progressAnimation; @override void initState() { super.initState(); // 初始化动画控制器,可自定义时长 _controller = AnimationController( duration: const Duration(seconds: 3), vsync: this, ); // 创建从0到1的进度动画,可添加Curve调整动画节奏 _progressAnimation = Tween<double>(begin: 0.0, end: 1.0).animate( CurvedAnimation(parent: _controller, curve: Curves.easeInOut), ); // 启动动画,也可以通过按钮触发_controller.forward()/_controller.reset()等 _controller.forward(); } @override void dispose() { // 记得销毁控制器避免内存泄漏 _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Row( children: [ const Text('left Text'), // 占满左右文本间的剩余空间 Expanded( child: LayoutBuilder( builder: (context, constraints) { return AnimatedBuilder( animation: _progressAnimation, builder: (context, child) { return Align( alignment: Alignment.centerLeft, child: Container( height: 24, // 自定义进度条高度 width: constraints.maxWidth * _progressAnimation.value, decoration: BoxDecoration( color: Colors.blueAccent, borderRadius: BorderRadius.circular(12), // 圆角效果 ), ), ); }, ); }, ), ), const SizedBox(width: 8), // 给右侧文本加个间距 const Text('right Text'), ], ), ); } }
方案二:进度条覆盖整个行宽度(文本悬浮在进度条上方)
如果希望进度条从左到右填充整个行的宽度,同时左右文本保持在两端不被遮挡,可以用Stack布局:
import 'package:flutter/material.dart'; class FullWidthProgressRow extends StatefulWidget { const FullWidthProgressRow({super.key}); @override State<FullWidthProgressRow> createState() => _FullWidthProgressRowState(); } class _FullWidthProgressRowState extends State<FullWidthProgressRow> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<double> _progressAnimation; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(seconds: 2), vsync: this, ); _progressAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller); // 循环播放动画(可选) _controller.repeat(reverse: true); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Stack( alignment: Alignment.center, children: [ // 底层进度条 AnimatedBuilder( animation: _progressAnimation, builder: (context, child) { return Container( height: 24, width: MediaQuery.of(context).size.width * _progressAnimation.value, color: Colors.green.withOpacity(0.4), ); }, ), // 上层的两端对齐文本 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: const [ Text('left Text', style: TextStyle(color: Colors.black87)), Text('right Text', style: TextStyle(color: Colors.black87)), ], ), ], ), ); } }
关键要点说明:
- 动画控制:通过
AnimationController可以自由控制动画的启动、暂停、反转、重置,你可以根据业务逻辑(比如按钮点击、数据加载进度)来触发这些操作。 - 进度条自定义:可以调整进度条的高度、颜色、圆角、透明度等样式,完全适配你的UI需求。
- 精准宽度计算:方案一中的
LayoutBuilder能准确获取左右文本之间的剩余空间,确保进度条不会超出预期区域。
你可以根据实际需求选择其中一种方案,或者结合两者的特点调整代码~
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

