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

Flutter:实现带环形进度指示器边框的Container组件

How to Implement a Container with Circular Progress Indicator Border

Hey there! I’ve run into this exact requirement before, and nesting plain Containers won’t cut it for that circular progress border effect. Let me share two reliable ways to pull this off:

Method 1: Stack + CircularProgressIndicator (Quick & Simple)

This approach uses Flutter’s built-in CircularProgressIndicator layered behind your content container to mimic a border progress effect. It’s great for fast implementation without custom painting.

Stack(
  alignment: Alignment.center,
  children: [
    // Circular progress indicator acting as the border
    CircularProgressIndicator(
      value: 0.7, // Progress value between 0 and 1
      strokeWidth: 4, // Thickness of the progress border
      valueColor: const AlwaysStoppedAnimation<Color>(Colors.blue),
      backgroundColor: Colors.grey.shade200,
    ),
    // Inner container with your content
    Container(
      width: 60,
      height: 60,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(30),
      ),
      child: const Icon(Icons.check, color: Colors.blue),
    ),
  ],
)
  • Adjust the strokeWidth to control how thick your progress border is.
  • Make sure the inner container’s size is slightly smaller than the progress indicator so the border remains visible.

Method 2: CustomPainter (Full Customization)

If you need more control over the border’s appearance (like rounded caps, custom start/end points), a custom painter is the way to go.

First, create a custom painter class:

import 'dart:math';
import 'package:flutter/material.dart';

class CircularProgressBorderPainter extends CustomPainter {
  final double progress;
  final Color progressColor;
  final Color backgroundColor;
  final double strokeWidth;

  CircularProgressBorderPainter({
    required this.progress,
    required this.progressColor,
    required this.backgroundColor,
    required this.strokeWidth,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = (size.width - strokeWidth) / 2;

    // Draw background ring
    final backgroundPaint = Paint()
      ..color = backgroundColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round;
    canvas.drawCircle(center, radius, backgroundPaint);

    // Draw progress ring
    final progressPaint = Paint()
      ..color = progressColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round;
    final arcAngle = 2 * pi * progress;
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      -pi / 2, // Start drawing from the top
      arcAngle,
      false,
      progressPaint,
    );
  }

  @override
  bool shouldRepaint(CircularProgressBorderPainter oldDelegate) {
    return oldDelegate.progress != progress ||
        oldDelegate.progressColor != progressColor ||
        oldDelegate.backgroundColor != backgroundColor ||
        oldDelegate.strokeWidth != strokeWidth;
  }
}

Then use it with your content container:

CustomPaint(
  size: const Size(80, 80),
  painter: CircularProgressBorderPainter(
    progress: 0.7,
    progressColor: Colors.blue,
    backgroundColor: Colors.grey.shade200,
    strokeWidth: 4,
  ),
  child: Container(
    width: 72,
    height: 72,
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(36),
    ),
    child: const Center(child: Icon(Icons.check, color: Colors.blue)),
  ),
)

Why Nesting Containers Didn’t Work

A regular Container’s border property creates a full, solid border—there’s no built-in way to make it a partial circular progress. You need to layer components or draw the progress manually to get that dynamic, partial border effect.

内容的提问来源于stack exchange,提问作者F.SO7

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:29:09