美文网首页AndroidFlutter圈子Android开发
初识 Flutter 的绘图组件 — CustomPaint

初识 Flutter 的绘图组件 — CustomPaint

作者: 岛上码农 | 来源:发表于2022-07-26 06:46 被阅读0次

    简介

    在有些场景中,我们会需要绘制一些高度定制化的组件,比如 UI 设计师给我们出了个难题 —— 弄一个奇形怪状的边框。看在 UI 设计师是一个漂亮小姐姐的份上,又不好意思说这个做不了(那样也很没面子😂)。这个时候我们就不能直接使用 Flutter 自带的那些组件了,而是需要手动绘制组件,那就会需要用到 CuntomPaint 组件。CustomPaint 组件和前端的 Canvas差不多,允许我们在一个画布上绘制各种元素,包括点、线、矩形、圆弧、文字、图片等等。

    CustomPaint 介绍

    CustomPaint是一个 Widget,其中有三个重要的参数:

    CustomPaint(
      child: childWidget(),
      foregroundPainter: foregroundPainter(),
      painter: backgroundPainter(),
    )
    
    • childCustomPaint的子组件;
    • painterforegroundPainter:都是 CustomPainter 类,用于定义 canvas 绘制的内容。区别在于,首先是执行 painter 的绘制指令。然后是在背景上渲染 child 子组件。最后,foregroundPainter 的内容会绘制在 child 上一层。
      绘图层叠次序

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

    CustomPainter 示例

    有了上面的基础概念后,我们来一个简单的示例来演示三个参数的层级关系。我们在backgroundPainter 上绘制一个蓝色的正方形,然后传入一个原型图片组件作为 child,最后是在 foregroundPainter 上绘制一个半透明的红色圆形遮住一部分图片。最终实现效果如下图,这样我们可以很好地了解三个元素的关系。

    层叠示例

    完整代码如下:

    import 'dart:ui';
    import 'package:flutter/material.dart';
    
    class BasicPaintPage extends StatelessWidget {
      const BasicPaintPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return CustomPaint(
          child: Center(
            child: ClipOval(
              child: Image.asset(
                'images/beauty.jpeg',
                width: 200,
                height: 200,
                fit: BoxFit.fitWidth,
              ),
            ),
          ),
          painter: BackgroundPainter(),
          foregroundPainter: ForegroundPainter(),
        );
      }
    }
    
    class BackgroundPainter extends CustomPainter {
      @override
      void paint(Canvas canvas, Size size) {
        canvas.drawColor(Color(0xFFF1F1F1), BlendMode.color);
        var center = size / 2;
        var paint = Paint()..color = Color(0xFF2080E5);
        paint.strokeWidth = 2.0;
    
        canvas.drawRect(
          Rect.fromLTWH(center.width - 120, center.height - 120, 240, 240),
          paint,
        );
      }
    
      @override
      bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return false;
      }
    }
    
    class ForegroundPainter extends CustomPainter {
      @override
      void paint(Canvas canvas, Size size) {
        var center = size / 2;
        var paint = Paint()..color = Color(0x80F53010);
        paint.strokeWidth = 2.0;
    
        canvas.drawCircle(
          Offset(center.width, center.height),
          100,
          paint,
        );
      }
    
      @override
      bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return false;
      }
    }
    
    

    其中在背景绘制中我们制定了canvas 的背景色,即下面这行代码:

    canvas.drawColor(Color(0xFFF1F1F1), BlendMode.color);
    

    其他代码就相对好理解了,BackgroundPainter 绘制了一个蓝色正方形,child 是一个居中的圆形图片,而 ForegroundPainter 则是在中间绘制了一个和圆形图片同等大小的,半透明的红色圆圈。于是就得到了我们想要的效果。

    总结

    本篇介绍了 CustomPaint 的基本使用,可以看到 CustomPaint使用起来并不复杂,但是真正复杂的是如何绘制图形,这个需要有比较好的数学知识支撑(当然,如果确实不会也可以搜索相关资料)。接下来的一篇我们来绘制一些常见的图形。

    相关文章

      网友评论

        本文标题:初识 Flutter 的绘图组件 — CustomPaint

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