• Flutter:CustomPaint与RenderObject自绘摘要


    一、CustomPaint自绘(类似自定义View):

    1.API说明:

    (1)CustomPaint说明:

    1. CustomPaint(
    2.   painter: ...,            //背景绘制,在自定义CustomPainter中绘制背景
    3.   foregroundPainter: ...,  //前景绘制,在自定义CustomPainter中绘制前景
    4.   size: Size(宽, 高),      //child为空时指定画布宽高,child不为空时忽略此参
    5.   isComplex: false,        //是否复杂绘制,是时用缓存策略(提高性能),否时不用
    6.   willChange: false,       //true时下一帧绘制会改变,false时不改变。isComplex=true时生效
    7.   child: ...               //子布局,可以为空
    8. )

    (2)Canvas画布:

    1. canvas.drawLine(开始点Offset, 结束点Offset, 画笔Paint);     //画线
    2. canvas.drawPoint(画笔Paint);                             //画点
    3. canvas.drawPath(路径Path, 画笔Paint);                    //画路径
    4. canvas.drawImage(图片Image, 左上角Offset, 画笔Paint);    //画图像
    5. canvas.drawRect(Rect矩形, Paint画笔);                    //画矩形
    6. canvas.drawCircle(圆心Offset, 半径数值, 画笔Paint);      //画圆
    7. canvas.drawOval(Rect矩形, Paint画笔);                    //画椭圆
    8. canvas.drawArc(Rect矩形, 开始角度, 持续角度, true扇区或false圆环, 画笔Paint); //画圆弧

    (3)Paint画笔:

    1. Paint paint = Paint()
    2.   ..isAntiAlias = true           //true抗锯齿,false有锯齿
    3.   ..style = PaintingStyle.stroke //画笔样式
    4.   ..strokeWidth = 2              //画笔粗细
    5.   ..color = Colors.red;          //画笔颜色

    (4)RepaintBoundary能提高性能:

    1. RepaintBoundary(//使用RepaintBoundary包裹CustomPaint,使自定义绘制不受Widget树影响,减少CustomPaint重绘
    2.   child: ...   
    3. )

    2.实现CustomPaint自绘:

    (1)实现自定义CustomPainter,绘制图形:

    1. class MyCustomPainter extends CustomPainter {
    2.   @override
    3.   void paint(Canvas canvas, Size size) {
    4.      //...在此处绘制自定义图形,例画路径
    5.      Path path = Path()
    6.     ..moveTo(0, 150)
    7.     ..lineTo(100, 0)
    8.     ..lineTo(200, 120)
    9.     ..lineTo(300, 50);
    10.     canvas.drawPath(path, mPaint);                         //画路径
    11.   }
    12.   @override
    13.   bool shouldRepaint(CustomPainter oldDelegate) => false;  //false不会重绘, true会重绘
    14. }

    (2)创建CustomPaint,并传入自定义CustomPainter:

    1. RepaintBoundary( //使用RepaintBoundary包裹CustomPaint,使自定义绘制不受Widget树影响,减少CustomPaint重绘
    2.   child: CustomPaint(
    3.       painter: MyCustomPainter(),            //背景绘制,在自定义CustomPainter中绘制背景
    4.       foregroundPainter: MyCustomPainter(),  //前景绘制,在自定义CustomPainter中绘制前景
    5.       size: Size(200, 100)                   //指定画布宽高
    6.   )
    7. );

    二、RenderObject自绘:

    1.实现自定义RenderObjectWidget类:

    1. class MyRenderObjectWidget extends LeafRenderObjectWidget{ //LeafRenderObjectWidget为RenderObjectWidget子类
    2.   @override
    3.   RenderObject createRenderObject(BuildContext context) {
    4.     return MyRenderObject();  //此处创建自定义RenderObject
    5.   }
    6.   @override
    7.   void updateRenderObject(context, MyRenderObject renderObject) {
    8.     //...此处更新自定义RenderObject状态
    9.   }
    10. }

    2.实现自定义RenderObject类:

    1. class MyRenderObject extends RenderBox{ //RenderBox为RenderObject子类
    2.   int pointer = 0;
    3.   @override
    4.   bool get isRepaintBoundary => true;
    5.   //测绘方式1,size由本组件决定
    6.   @override
    7.   void performLayout() {
    8.     //父Widget有固定宽高时使用父的,没有则此处指定默认值
    9.     size = constraints.constrain(constraints.isTight ? Size.infinite : Size(100, 100));
    10.   }
    11.   //测绘方式2,size由parent组件决定,必须sizedByParent返回true
    12.   // @override
    13.   // void performResize() {
    14.   //   size = constraints.biggest;
    15.   // }
    16.   // @override
    17.   // bool get sizedByParent => true;
    18.   @override
    19.   void paint(PaintingContext context, Offset offset) {//paint方法实现自定义绘图
    20.     //...绘图逻辑
    21.   }
    22.   @override
    23.   bool hitTestSelf(Offset position) => true;  //true时响应点击事件,false忽略点击事件
    24.   @override
    25.   void handleEvent(PointerEvent event, covariant BoxHitTestEntry entry) { //处理点击事件
    26. if (event.down) {
    27. pointer = event.pointer;
    28. return;
    29. }
    30. if (event.pointer == pointer && size.contains(event.localPosition)) { //判断点击是否在本组件内
    31. log("触发点击了 handleEvent >> pointer: ${event.pointer} localPosition: ${event.localPosition}");
    32. }
    33.   }
    34. }

  • 相关阅读:
    在AWS上部署一个网站
    文件上传及CSRF+Selfxss
    【知识点】web安全怎么做
    章鱼应用链|UniqueOne 构建一体化的 NFT 和元宇宙的体验
    数据结构刷题:第五天
    基于 FPGA 实现 IIC(I2C) 协议控制 EEPROM 读写操作
    【JUC】交换器Exchanger详解
    细数SkyEye异构仿真的5大特色
    PSCA电源控制集成之分布式PPU
    【Java 进阶篇】Java Tomcat 入门指南
  • 原文地址:https://blog.csdn.net/a526001650a/article/details/127965411