这里的难点在于怎么绘制田字格的虚线。
已经有
path_drawing
的package解决这个问题,在本例中,直接复制其虚线代码到项目中。
大家也可以直接使用package作为依赖
全部源码:
import 'package:flutter/material.dart'
import 'package:meta/meta.dart'
import 'dart:ui'
void main() => runApp(MyApp())
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
home: HomePage(),
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Font'),
body: Center(
child: Stack(
alignment: Alignment.center,
children: <Widget>[
CustomPaint(
size: Size(200, 200),
painter: Background(),
Text(
style: TextStyle(fontSize: 120),
class Background extends CustomPainter {
@override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true
@override
void paint(Canvas canvas, Size size) {
//绘制田字格核心代码
final paint1 = Paint()
..style = PaintingStyle.stroke
..color = Colors.black
..strokeWidth = 2
canvas.drawLine(Offset(0, 0), Offset(size.width, 0), paint1)
canvas.drawLine(Offset(size.width, 0), Offset(size.width, size.width), paint1)
canvas.drawLine(Offset(size.width, size.width), Offset(0, size.width), paint1)
canvas.drawLine(Offset(0, size.width), Offset(0, 0), paint1)
final paint2 = Paint()
..style = PaintingStyle.stroke
..color = Colors.black
..strokeWidth = 1
var path = Path()
path.moveTo(0, 0)
path.lineTo(size.width, size.width)
path.moveTo(0, size.width)
path.lineTo(size.width, 0)
path.moveTo(0, size.width / 2)
path.lineTo(size.width, size.width / 2)
path.moveTo(size.width / 2, 0)
path.lineTo(size.width / 2, size.width)
canvas.drawPath(dashPath(path, dashArray: CircularIntervalList([5, 5])), paint2)
//以下是path_drawing实现虚线的部分
Path dashPath(
Path source, {
@required CircularIntervalList<double> dashArray,
DashOffset dashOffset,
assert(dashArray != null)
if (source == null) {
return null
dashOffset = dashOffset ?? const DashOffset.absolute(0.0)
// TODO: Is there some way to determine how much of a path would be visible today?
final Path dest = Path()
for (final PathMetric metric in source.computeMetrics()) {
double distance = dashOffset._calculate(metric.length)
bool draw = true
while (distance < metric.length) {
final double len = dashArray.next
if (draw) {
dest.addPath(metric.extractPath(distance, distance + len), Offset.zero)
distance += len
draw = !draw
return dest
enum _DashOffsetType { Absolute, Percentage }
class DashOffset {
DashOffset.percentage(double percentage)
: _rawVal = percentage.clamp(0.0, 1.0) ?? 0.0,
_dashOffsetType = _DashOffsetType.Percentage
const DashOffset.absolute(double start)
: _rawVal = start ?? 0.0,
_dashOffsetType = _DashOffsetType.Absolute
final double _rawVal
final _DashOffsetType _dashOffsetType
double _calculate(double length) {
return _dashOffsetType == _DashOffsetType.Absolute ? _rawVal : length * _rawVal
class CircularIntervalList<T> {
CircularIntervalList(this._vals)
final List<T> _vals
int _idx = 0
T get next {
if (_idx >= _vals.length) {
_idx = 0
return _vals[_idx++]
复制代码
dashPath及其后面的内容,是path_drawing实现虚线的部分,在canvas中绘制曲线也相当简单
canvas.drawPath(dashPath(path, dashArray: CircularIntervalList([5, 5])), paint2);
piccalilli
Flutter
-
3474
-
程序员老鱼
掘金·日新计划
ChatGPT
OpenAI
-
621
-
风雨_83
掘金·日新计划
Flutter
-
4143
-
panpanWang
Flutter
Android
-
508
-
风雨_83
掘金·日新计划
Flutter
-
7029
-
张风捷特烈
Android
Flutter
掘金·日新计划
-
996
-
Realank Liu
iOS Developer @ UCar inc