【问题标题】:Create custom circular progress indicator in flutter with custom stroke cap使用自定义笔画帽在颤动中创建自定义圆形进度指示器
【发布时间】:2021-07-23 22:33:55
【问题描述】:

我需要创建这个百分比指标

我怎样才能做到这一点?我在 Flutter 中尝试过 percent_indicator 包,但主要问题是我们的 strokeCap 选项数量有限。我也尝试过用两条弧线来做到这一点,但问题仍然存在。有没有一种方法可以创建自定义的 strokeCap,或者没有 canvas.drawArc 的另一种方法?

【问题讨论】:

    标签: flutter user-interface flutter-canvas flutter-circularprogressindicator


    【解决方案1】:

    您可以使用 CustomPainter 实现此目的。以下是我的解决方案。

    注意 您可以传入一个动态值来更新进度条的值。我没有这样做,因为一旦渲染正确,实现它应该是微不足道的;)。您还可以根据需要更新颜色!

    import 'package:flutter/material.dart';
    import 'package:vector_math/vector_math.dart' as vmath;
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          home: TestPage(),
        );
      }
    }
    
    class TestPage extends StatelessWidget {
      const TestPage({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Container(
              width: 200,
              height: 200,
              child: CustomPaint(
                painter: MyPainter(),
                child: Container(),
              ),
            ),
          ),
        );
      }
    }
    
    class MyPainter extends CustomPainter {
      @override
      void paint(Canvas canvas, Size size) {
        // Get the center of the canvas 
        final center = Offset(size.width / 2, size.height / 2);
        
        // Draw the gray background seen on the progress indicator
        // This will act as the background layer.
        canvas.drawCircle(
          center,
          85,
          Paint()
            ..style = PaintingStyle.stroke
            ..color = Colors.black12
            ..strokeWidth = 30,
        );
    
        // Create a new layer where we will be painting the 
        // actual progress indicator
        canvas.saveLayer(
          Rect.fromCenter(center: center, width: 200, height: 200),
          Paint(),
        );
    
        // Draw the light green portion of the progress indicator
        canvas.drawArc(
          Rect.fromCenter(center: center, width: 170, height: 170),
          vmath.radians(0),
          vmath.radians(200),
          false,
          Paint()
            ..style = PaintingStyle.stroke
            ..strokeCap = StrokeCap.round
            ..color = Colors.green[100]
            ..strokeWidth = 30,
        );
    
        // Draw the dark green portion of the progress indicator
        // Basically, this covers the entire progress indicator circle.
        // But because we have set the blending mode to srouce-in (BlendMode.srcIn), 
        // only the segment that is overlapping with the lighter portion will be visible.
        canvas.drawArc(
          Rect.fromCenter(center: center, width: 155, height: 155),
          vmath.radians(0),
          vmath.radians(360),
          false,
          Paint()
            ..style = PaintingStyle.stroke
            ..strokeCap = StrokeCap.round
            ..color = Colors.green
            ..strokeWidth = 15
            ..blendMode = BlendMode.srcIn,
        );
        // we fatten the layer
        canvas.restore();
      }
    
      @override
      bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
    }
    

    您应该得到如下所示的输出:

    【讨论】:

    • 非常感谢!
    • 随时 ;) 我很高兴它有帮助
    • 您能否将 cmets 添加到您的 MyPainter 课程中?我是 Flutter 的新手,很难理解。 @YounssAITMOU
    • 我添加了一些可以帮助理解代码的 cmets。如果您需要具体的帮助,请告诉我有什么不清楚的地方,我很乐意澄清;)
    猜你喜欢
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 2023-04-02
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多