You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:45:25