【问题标题】:Flutter - Container with ring progress indicator borderFlutter - 带有环形进度指示器边框的容器
【发布时间】:2021-11-19 15:13:43
【问题描述】:

我正在尝试实现一个具有进度指示器边框的容器,如下图所示:

我尝试在另一个容器中使用一个容器来实现它(一个容器用于外部白色边框,一个容器用于内部蓝色背景并带有图标),但我无法实现进度指示器效果。

有谁知道我怎样才能做到这一点?

谢谢

【问题讨论】:

  • 试试CustomPainter
  • 您是否需要为进度使用一些自定义值?还是一个简单的进度动画应该可以工作?
  • @YeasinSheikh 你是什么意思?
  • @pedropimont 我愿意给它一个从 0 到 100 的值,代表进度(0 根本没有边框,100 是全边框)
  • 我认为使用CustomPainter 很容易制作您需要输出对吗?

标签: flutter dart flutter-layout


【解决方案1】:

如果您不想使用 CustomPainter,可以尝试使用 Stack 小部件来实现这一目标

你可以在DartPad看到这个例子

使用第二个CircularProgressIndicator 上的value 属性以使用setState 或您喜欢的任何其他状态管理技术更新值

import 'package:flutter/material.dart';

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 MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: const [
        CircleAvatar(
          backgroundColor: Colors.white,
          radius: 24,
          child: Icon(Icons.check),
        ),
        SizedBox(
          width: 50,
          height: 50,
          child: CircularProgressIndicator(
            color: Colors.grey,
            value: 1,
          ),
        ),
        SizedBox(
          width: 50,
          height: 50,
          child: CircularProgressIndicator(
            color: Colors.blue,
            value: .3, // Change this value to update the progress
          ),
        ),
      ],
    );
  }
}

【讨论】:

  • 看起来不错。谢谢
【解决方案2】:

有一个名为 CircularProgressIndicator 的小部件似乎正是您所追求的。

如何使用:

CircularProgressIndicator(
              backgroundColor: Colors.white, 
              color: Colors.purple.withAlpha(100), 
              strokeWidth: 5,
              value: value, //
            ),

backgroundColor: 用于白色背景

color: 紫色覆盖层

strokeWidth: 你想要的厚度

value指标实际进度

要将箭头放在顶部,只需使用一个圆形的白色容器(使用BoxDecorationshape: BoxShape.circle 使其成为一个圆圈),然后使用Stack 小部件将箭头放在它上面。

希望这会有所帮助!

【讨论】:

    【解决方案3】:
    
    class ProgressPainter extends CustomPainter {
      final double value;
      double deg2rad(double deg) => deg * pi / 180;
      ProgressPainter({
        required this.value,
      });
    
      @override
      void paint(Canvas canvas, Size size) {
        Paint paint = Paint()..color = Colors.blueGrey;
    
        final rect = Rect.fromCenter(
            center: Offset(size.height / 2, size.width / 2),
            width: size.width,
            height: size.height);
    
        canvas.drawArc(
            rect,
            deg2rad(-90),
            deg2rad(
              (value * 360) / 100, // % to degree
            ),
            true,
            paint);
      }
    
      @override
      bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return false;
      }
    }
    
    

    并使用

          CustomPaint(
                      painter: ProgressPainter(value: sliderVal),
                      child: const SizedBox(
                        height: 100,
                        width: 100,
                        child: Icon( // your inner widget
                          Icons.ac_unit,
                          size: 100,
                        ),
                      ),
                    ),
    

    经过测试的小部件:

    
    class _MyHomePageState extends State<MyHomePage> {
      double sliderVal = 0;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text(widget.title)),
          body: Center(
            child: Column(
              children: [
                CustomPaint(
                  painter: ProgressPainter(value: sliderVal),
                  child: const SizedBox(
                    height: 100,
                    width: 100,
                    child: Icon(
                      Icons.ac_unit,
                      size: 100,
                    ),
                  ),
                ),
                Slider(
                  value: sliderVal,
                  min: 0,
                  max: 100,
                  onChanged: (value) {
                    setState(() {
                      sliderVal = value;
                    });
                  },
                )
              ],
            ),
          ),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-22
      • 2022-11-18
      • 2011-04-23
      • 2018-10-19
      • 2015-09-06
      • 1970-01-01
      • 2015-11-14
      • 2020-03-28
      相关资源
      最近更新 更多