Flutter是否有带间隔槽的进度条?能否修改LinearProgressIndicator实现该样式?
Flutter 自定义目标样式进度条方案
- Flutter官方组件库没有原生提供你需要的这种进度条样式。
- 可以通过修改
LinearProgressIndicator或者自定义绘制来实现该样式,但直接修改LinearProgressIndicator的灵活性较低,更推荐自定义绘制的方式,当然也可以基于它做叠加扩展。
基于LinearProgressIndicator的快速扩展思路
如果只是需要在现有进度条基础上添加分段或标记效果,用Stack组件将进度条和自定义标记元素组合即可:
Stack( alignment: Alignment.centerLeft, children: [ LinearProgressIndicator( value: 0.6, backgroundColor: Colors.grey.shade300, valueColor: const AlwaysStoppedAnimation<Color>(Colors.blue), ), // 添加分段分隔标记 Row( children: List.generate(5, (index) { return Container( width: 4, height: 8, margin: EdgeInsets.only(left: index == 0 ? 20 : 24), color: Colors.white, ); }), ), ], )
自定义绘制实现(推荐)
如果需要完全匹配配图样式,使用CustomPaint自定义绘制是最灵活的方式,示例代码如下:
class CustomSegmentedProgressBar extends StatelessWidget { final double progress; final int totalSegments; final Color activeColor; final Color inactiveColor; final double segmentHeight; final double gapWidth; const CustomSegmentedProgressBar({ super.key, required this.progress, this.totalSegments = 5, this.activeColor = Colors.blue, this.inactiveColor = Colors.grey.shade300, this.segmentHeight = 8, this.gapWidth = 4, }); @override Widget build(BuildContext context) { final totalWidth = (segmentHeight * totalSegments) + (gapWidth * (totalSegments - 1)); return CustomPaint( size: Size(totalWidth, segmentHeight), painter: _SegmentedProgressPainter( progress: progress, totalSegments: totalSegments, activeColor: activeColor, inactiveColor: inactiveColor, gapWidth: gapWidth, ), ); } } class _SegmentedProgressPainter extends CustomPainter { final double progress; final int totalSegments; final Color activeColor; final Color inactiveColor; final double gapWidth; _SegmentedProgressPainter({ required this.progress, required this.totalSegments, required this.activeColor, required this.inactiveColor, required this.gapWidth, }); @override void paint(Canvas canvas, Size size) { final segmentWidth = (size.width - (gapWidth * (totalSegments - 1))) / totalSegments; final activePaint = Paint()..color = activeColor; final inactivePaint = Paint()..color = inactiveColor; final completedSegments = (progress * totalSegments).floor(); final partialProgress = (progress * totalSegments) - completedSegments; for (int i = 0; i < totalSegments; i++) { final xOffset = i * (segmentWidth + gapWidth); var drawWidth = segmentWidth; // 处理未完全填充的最后一段 if (i == completedSegments && partialProgress > 0) { drawWidth = segmentWidth * partialProgress; } // 绘制圆角进度分段 canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH(xOffset, 0, drawWidth, size.height), Radius.circular(size.height / 2), ), i < completedSegments ? activePaint : inactivePaint, ); } } @override bool shouldRepaint(_SegmentedProgressPainter oldDelegate) { return progress != oldDelegate.progress || activeColor != oldDelegate.activeColor || inactiveColor != oldDelegate.inactiveColor; } }
使用示例
CustomSegmentedProgressBar( progress: 0.6, // 代表60%的完成进度 totalSegments: 5, )
内容的提问来源于stack exchange,提问作者Patola
相关产品推荐
相关产品推荐

