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

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

这种很鸡肋的需求,是来自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 {
  @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绘制弧形进度条)