flutter3.0学习笔记

CustomPaint(自定义绘制)

Preview
  • CustomPaint

CustomPaint

CustomPaint可以自定义动画,实现很多酷炫的动画效果。

  • 构造函数
const CustomPaint({
    super.key,
    this.painter,//背景画笔,会显示在子节点后面
    this.foregroundPainter,//前景画笔,会显示在子节点前面
    //当child为null时,代表默认绘制区域大小,
    //如果有child则忽略此参数,画布尺寸则为child尺寸。
    //如果有child但是想指定画布为特定大小,可以使用SizeBox包裹CustomPaint实现。
    this.size = Size.zero,
    this.isComplex = false,//是否复杂的绘制,如果是,Flutter会应用一些缓存策略来减少重复渲染的开销。
    this.willChange = false,//和isComplex配合使用,当启用缓存时,该属性代表在下一帧中绘制是否会改变。
    super.child,
  }) 

可以看到,绘制时我们需要提供前景或背景画笔,两者也可以同时提供。我们的画笔需要继承CustomPainter类,我们在画笔类中实现真正的绘制逻辑。

CustomPainter提供了一个paint绘图方法供我们绘制图形,该方法携带canvassize两个参数,其中 canvas 是画布,size 是画布大小。canvas 提供了很多绘制图形的方法,比如绘制路径、矩形、圆形和线条等等。

void paint(Canvas canvas, Size size);

Paint 的初始化:

Paint _paint = Paint()
  ..color = Colors.deepOrange//画笔颜色
  ..strokeCap = StrokeCap.round //画笔笔头类型
  ..isAntiAlias = true //是否开启抗锯齿
  ..blendMode = BlendMode.src//颜色混合模式
  ..style = PaintingStyle.fill //画笔样式,默认为填充
  ..colorFilter = ColorFilter.mode(Colors.blueAccent,
      BlendMode.src) //颜色渲染模式
  ..maskFilter = MaskFilter.blur(BlurStyle.inner, 3.0) //模糊遮罩效果
  ..filterQuality = FilterQuality.high //颜色渲染模式的质量
  ..strokeWidth = 5.0; //画笔的宽度复制代码
  • 创建一个MyPainter绘画继承CustomPainter

CustomPainter中提定义了一个虚函数paintpaint有两个参数:CanvasSize

 class MyPainter extends CustomPainter{
   @override
   void paint(Canvas canvas,Size size){
     //绘制动画
   }
   @override
   bool shouldRepaint(MyPainter oldDelegate){
     //shouldRepaint方法通常在当前实例和旧实例属性不一致时返回true
     return this != oldDelegate;
   }
 }
  • 绘制点drawPoints
class MyPainter extends CustomPainter{
  @override
  void paint(Canvas canvas,Size size){
  //绘制动画
  //定义颜色宽度
    Paint _paint = Paint()
      ..color = Colors.red
      ..strokeWidth = 5;
   
    //画点
    var points = [
      Offset(0, 0),
      Offset(size.width / 2, size.height / 2),
      Offset(size.width, size.height),
    ];
    //画点
    canvas.drawPoints(PointMode.points, points, _paint);
  }
  @override
  bool shouldRepaint(MyPainter oldDelegate){
    //shouldRepaint方法通常在当前实例和旧实例属性不一致时返回true
    return this != oldDelegate;
  }
}

image.png

  • 画线drawLine
//画线
    canvas.drawLine(Offset(1, 1),Offset(size.width, size.height) , _paint);

image.png

  • 画路径drawPath
class MyPainter extends CustomPainter{
  @override
  void paint(Canvas canvas,Size size){
    Paint _paint = Paint()
      ..color = Colors.red
      ..strokeWidth = 5
      ..style = PaintingStyle.stroke;
    //路径一个三角形
    var _path = Path()
    ..moveTo(0, 0)// 移动起点到(0,0)
    ..lineTo(size.width, 0)
    ..lineTo(size.width, size.height)
    //..lineTo(50, 100)//画条斜线
    //..lineTo(100, 100)//画条直线
    //..moveTo(50, 50)// 移动起点到
   // ..lineTo(2*size.width, 2*size.height)
    ..close();// 封闭当前路径
    canvas.drawPath(_path, _paint);
  }
  @override
  bool shouldRepaint(MyPainter oldDelegate){
    //shouldRepaint方法通常在当前实例和旧实例属性不一致时返回true
    return false;
  }
}

image.png

  • 画圆drawCircle
 //canvas.drawCircle(c, radius, paint)
 //画圆
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 20, _paint);

image.png

  • 椭圆drawOval
//画椭圆
canvas.drawOval(Rect.fromLTRB(0, 0, size.width, size.height/2), _paint);

image.png

  • 绘制弧drawArc
//绘制弧
//canvas.drawArc(rect, startAngle, sweepAngle, useCenter, paint)
 canvas.drawArc(Rect.fromLTRB(0, 0, size.width,size.height), 0, pi/2, true, _paint);

image.png

  • 绘制矩形drawRect
 //画矩形drawRect
var rect = Rect.fromCenter(center: Offset(size.width/2,size.height/2), width: 100, height: 100);
或者
var rect = Rect.fromLTRB(0, 0, size.width/2, size.height/2);
或者 
var rect = Rect.fromLTWH(0, 0,size.width/2, size.height/2);
或者
var rect = Rect.fromPoints(Offset(0, 0), Offset(size.width/2, size.height/2));
    
canvas.drawRect(rect, _paint);

image.png

  • 绘制圆角矩形 drawRRect
//绘制圆角矩形
canvas.drawRRect(rrect, paint)
canvas.drawRRect(RRect.fromLTRBR(0, 0, size.width, size.height, Radius.circular(10)), _paint);

image.png