我想创建容器,在它的边界上,我想显示一个环形进度条,我如何实现它,有人能帮我吗

如下图所示:

黄色的圆圈是一个容器,我想在容器边框上显示进度条,在中间我想显示进度百分比

enter image description here

推荐答案

这里有一个最小的代码,它使用CustomPaintTweenAnimationBuilder实现了与您想要的非常接近的东西.

来自DARTPAD的屏幕:

enter image description here

代码:

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

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class BorderPainter extends CustomPainter {
  final double currentState;

  BorderPainter({required this.currentState});

  @override
  void paint(Canvas canvas, Size size) {

    double strokeWidth = 5;
    Rect rect = const Offset(5,5) & Size(size.width - 10, size.height - 10);

    var paint = Paint()
      ..color = Colors.white
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke;

      double startAngle = -pi / 2;
      double sweepAmount = currentState * pi;

      canvas.drawArc(rect, startAngle, sweepAmount, false, paint);
  }


  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: TweenAnimationBuilder(
        tween: Tween(begin: 0.0, end: 2.0),
        duration: const Duration(seconds: 10),
        builder: (context, value, child) {
          return Container(
            width: 100,
            height: 100,
            decoration: const BoxDecoration(
              shape: BoxShape.circle,
              color: Colors.orange
            ),
            child: CustomPaint(
              painter: BorderPainter(currentState: value),
              child: Center(
                child: Text(
                  '${value * 100 ~/ 2.0}%',
                ),
              ),
            ),
          );
        }
      ),
    );
  }
}

这篇伟大的文章的功劳:https://medium.com/@callumdixon941/creating-awesome-animated-custom-borders-in-flutter-with-canvas-90cf755cc29f

Flutter相关问答推荐

Flutter -使用最小高度展开

使用自定义控制器将项插入到ListView中时行为不正确

带有可滚动页面(不包括分页区)的Flutter 页面视图

如何在Flutter 中不从getX库中初始化GetxController中的变量

我不能在Fighting中裁剪图片输入错误,否则应用程序会崩溃

我有相关的下拉菜单Flutter Windows应用程序的问题

无法在仿真器上运行Flutter 项目-文件名太长错误

Flutter守护进程无法启动

顶部对齐ListTile的[前导、标题、尾随]小部件

Flutter 附近的连接

如何使用 Material3 创建带有高度的完美白色提升按钮?

尽管我的 url 链接正确,但 ArgumentError(无效参数:URI 文件中未指定主机:///)错误

以编程方式在 flutter 中安装 apk 时解析错误

如何删除或隐藏覆盖

为什么将 bloc 提供程序放在单独的文件/类中会引发错误?

如何在向下滚动时隐藏顶部卡片并在向上滚动时出现?

为什么 orientation == Orientation.portrait 总是正确的,尽管我的设备已经处于横向

Getx Flutter 在更新值时抛出空错误

Flutter:如何将列表转换为字符串?

Navigator.push '!_debugLocked' 上的错误:不正确