美文网首页Flutter
在Flutter中使用Canvas绘制弧形进度条

在Flutter中使用Canvas绘制弧形进度条

作者: Marsh_J | 来源:发表于2020-08-24 11:54 被阅读0次

    啊......这......

    这种很鸡肋的需求,是来自WX某公众号推送的恰饭文章中偶然发现的,整体为弧形卡片设计的音乐播放器,包括音乐播放的进度条,而后觉得弧形进度条因吹斯汀,翻遍已有的Flutter教程帖后,并没有发现类似的帖子,所以我来了!

    value值为0时
    value值改变时

    本人Flutter萌新,第一次发文章,代码写的比较烂,还望大佬嘴下留情......

    话不多说,直接开整:

    一、进度条的属性以及成员变量

    Flutter中为我们提供了封装好的组件CustomerPaint Widget,这个组件与画笔Paint Widget组合使用就可以绘制出需要的图形,在这之前,我们需要先创建一个继承于基类的绘制类。

    进度条最直观的就是颜色,因此就需要前景色和背景色,初次之外还有其他参数,这里就不一一列举了,直接上代码:

    class Progress extends CustomPainter {
      final Color backgroundColor;      //背景色
      final Color progressColor;        //前景色
      final double startPointAngle;     //Canvas绘制开始位置
      final double endPointAngle;       //结束位置
      final bool centerClose;           //圆弧是否闭合
      final double radius;              //半径
      final double lineWidth;           //所绘制线条的宽度
      final double value;               //进度条的value
      final TextStyle style;            //进度条文本风格(非必须)
      final String completeText;        //进度条文本(非必须)
    
      const Progress(
          {this.backgroundColor,
          this.progressColor,
          this.startPointAngle,
          this.endPointAngle,
          this.centerClose,
          this.radius,
          this.lineWidth,
          this.value,
          this.style,
          this.completeText});
    }
    

    如上所述,列举了一些基本的属性,也可以根据需要添加其他参数

    二、初始化画笔Paint,调用Canvas绘制图形

    在绘制类中重写paint()shouldRepaint()方法

    在我们所创建的继承于基类CustomPainter的绘制类中,会有如下两个方法,需要我们进行重写:

    class ProgresPainter extends CustomPainter {
      @override
      void paint(Canvas canvas, Size size) {
        // TODO: implement paint
      }
      
      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        // TODO: implement shouldRepaint
        return null;
      }
    

    重写paint()方法:

    void paint(Canvas canvas, Size size) {
        // TODO: implement paint
        Paint paint = Paint()   //初始化画笔
          ..color = backgroundColor //背景颜色
          ..style = PaintingStyle.stroke    //画笔样式
          ..strokeCap = StrokeCap.round //画笔笔头类型
          ..strokeWidth = lineWidth;    //画笔的宽度
        Rect rect = Rect.fromCircle(
            center: Offset(size.width / 2, size.height / 2), radius: radius);
            
    //通过Canvas绘制一条弧线
        canvas.drawArc(rect, startPointAngle, endPointAngle, centerClose, paint);
    //背景弧线绘制完成
    
        paint
          ..color = progressColor   //前景色
          ..strokeWidth = lineWidth + 1.0   //画笔宽度,在这里我们设置得比背景的宽度稍宽些
          ..style = PaintingStyle.stroke
          ..strokeCap = StrokeCap.round;
        canvas.drawArc(
            rect, startPointAngle, endPointAngle * value, centerClose, paint);
      }
    //前景弧线绘制完成
    

    重写shouldRepaint()方法:

    bool shouldRepaint(CustomPainter oldDelegate) {
        // TODO: implement shouldRepaint
        return true;
      }
    

    三、在其他Widget中使用绘制好的进度条

    为了更快捷的预览到进度条的效果,在这里我们直接使用SliderWidget来控制value的值。
    首先,创建一个StatefulWidget

    class ArcProgress extends StatefulWidget {
      double value; //在其他地方调用该Widget时,可以直接给value赋值
    
      ArcProgress({
        this.value,
      });
      @override
      _ArcProgressState createState() => _ArcProgressState();
    }
    
    class _ArcProgressState extends State<ArcProgress> {
      @override
      Widget build(BuildContext context) {
        return CustomPaint(
          child: Slider(    //在这里我们直接使用Slider对value进行赋值,实际使用时,应当移除
              value: widget.value,
              onChanged: (value) {
                setState(() {
                  widget.value = value;
                });
              }),
          painter: Progress(
              backgroundColor: Colors.grey, //设置背景色
              progressColor: Colors.amber,  //设置前景色
              radius: MediaQuery.of(context).size.width,    //设置背景色
              lineWidth: 5.0,   //设置线条宽度(此处为背景线条宽度)
              startPointAngle: math.pi - (math.pi / 9), //设置起始点
              endPointAngle: -(7 * math.pi / 9),
              centerClose: false,   //是否闭合,闭合后即为扇形
              value: widget.value,
          ),
        );
      }
    }
    

    ==在其他Widget中直接使用CustomPainter绘制的图形时,一定要在父控件的child里使用CustomPaint进行包裹==

    到这里,就已经完成了绘制和使用了。此文章并没有什么技术可言,初次发文,希望大家见谅

    相关文章

      网友评论

        本文标题:在Flutter中使用Canvas绘制弧形进度条

        本文链接:https://www.haomeiwen.com/subject/tuxnjktx.html