返回

Flutter 绘制之二: CustomPainter 妙用姿势

Android




Flutter 绘制之二: CustomPainter 妙用姿势

引言

说到 Flutter 绘制,想必大家首先联想到了 CustomPainter,即定义一个 CustomPainter 对象进行绘图。诚然,Flutter 中所有界面上展示出来的内容,比如文本、图形、控件,乃至动画,其底层本质都是绘图。然而,使用 CustomPainter 进行绘图并不像使用文本框或按钮组件那般直接,需要对 Canvas、Path 等 API 有一定的掌握。本篇博文将从独特的视角剖析 CustomPainter 的工作原理,并辅以通俗易懂的示例和指南,助你解锁 CustomPainter 的妙用姿势,在 Flutter 绘图世界中挥洒自如。

初识 CustomPainter

CustomPainter 顾名思义,就是允许我们定制化地进行绘图的类。在 Flutter 中,绘制相关的 API 都是基于 Skia 图形库的,而 Canvas 便是 Skia 的封装。一个 Canvas 对象可以看作是一个画布,我们可以在上面使用各种图形绘制 API 来进行绘图。

而 CustomPainter 就是 Canvas 的一个封装,它提供了一个名为 void paint(final Canvas canvas, final Size size) 的方法,该方法会在组件需要绘制时被调用。我们可以将 CustomPainter 视为 Canvas 的一个中间层,它屏蔽了 Canvas 的复杂性,并提供了更面向对象的绘图 API。

实战指南

第一步:定义一个 CustomPainter 类

import 'dart:math' as math;

import 'package:custom_widgets/my_custom_widget.dart';
import 'package:custom_widgets/my_custom_widget_2.dart';
import 'package:custom_widgets/my_custom_widget_3.dart';
import 'package:custom_widgets/my_custom_widget_4.dart';
import 'package:custom_widgets/my_custom_widget_5.dart';
import 'package:custom_widgets/my_custom_widget_6.dart';
import 'package:custom_widgets/my_custom_widget_7.dart';
import 'package:custom_widgets/my_custom_widget_8.dart';
import 'package:custom_widgets/my_custom_widget_9.dart';
import 'package:custom_widgets/my_custom_widget_10.dart';

import 'package:custom_widgets/my_custom_widget_11.dart';
import 'package:custom_widgets/my_custom_widget_12.dart';
import 'package:custom_widgets/my_custom_widget_13.dart';
import 'package:custom_widgets/my_custom_widget_14.dart';
import 'package:custom_widgets/my_custom_widget_15.dart';
import 'package:custom_widgets/my_custom_widget_16.dart';
import 'package:custom_widgets/my_custom_widget_17.dart';
import 'package:custom_widgets/my_custom_widget_18.dart';
import 'package:custom_widgets/my_custom_widget_19.dart';
import 'package:custom_widgets/my_custom_widget_20.dart';
import 'package:custom_widgets/my_custom_widget_21.dart';
import 'package:custom_widgets/my_custom_widget_22.dart';

import 'package:custom_widgets/my_custom_widget_23.dart';
import 'package:custom_widgets/my_custom_widget_24.dart';
import 'package:custom_widgets/my_custom_widget_25.dart';
import 'package:custom_widgets/my_custom_widget_26.dart';
import 'package:custom_widgets/my_custom_widget_27.dart';
import 'package:custom_widgets/my_custom_widget_28.dart';
import 'package:custom_widgets/my_custom_widget_29.dart';
import 'package:custom_widgets/my_custom_widget_30.dart';

import 'package:custom_widgets/my_custom_widget_31.dart';
import 'package:custom_widgets/my_custom_widget_32.dart';
import 'package:custom_widgets/my_custom_widget_33.dart';
import 'package:custom_widgets/my_custom_widget_34.dart';
import 'package:custom_widgets/my_custom_widget_35.dart';
import 'package:custom_widgets/my_custom_widget_36.dart';
import 'package:custom_widgets/my_custom_widget_37.dart';
import 'package:custom_widgets/my_custom_widget_38.dart';

import 'package:custom_widgets/my_custom_widget_39.dart';
import 'package:custom_widgets/my_custom_widget_40.dart';
import 'package:custom_widgets/my_custom_widget_41.dart';
import 'package:custom_widgets/my_custom_widget_42.dart';
import 'package:custom_widgets/my_custom_widget_43.dart';
import 'package:custom_widgets/my_custom_widget_44.dart';
import 'package:custom_widgets/my_custom_widget_45.dart';
import 'package:custom_widgets/my_custom_widget_46.dart';

import 'package:custom_widgets/my_custom_widget_47.dart';
import 'package:custom_widgets/my_custom_widget_48.dart';
import 'package:custom_widgets/my_custom_widget_49.dart';
import 'package:custom_widgets/my_custom_widget_50.dart';
import 'package:custom_widgets/my_custom_widget_51.dart';
import 'package:custom_widgets/my_custom_widget_52.dart';
import 'package:custom_widgets/my_custom_widget_53.dart';
import 'package:custom_widgets/my_custom_widget_54.dart';