Flutter绘制虚线的方法

  • Post author:
  • Post category:其他


Flutter 自带的 Canvas 并没有 Android 中的 Canvas 那么强大,连虚线都不支持。

今天周日,下午抽时间写了两个 Canvas 扩展函数,实现了绘制虚线线段和虚线矩形。

效果图如下:

具体实现代码如下:

import 'dart:math';

import 'package:flutter/material.dart';

///Flutter绘制虚线演示
void main() {
  runApp(MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter绘制虚线-wtp'),
        ),
        body: Container(
          color: Colors.black,
          child: AspectRatio(
            aspectRatio: 1,
            child: CustomPaint(
              painter: MyPainter(),
            ),
          ),
        ),
      )));
}

class MyPainter extends CustomPainter {
  Rect _rect;
  Paint _paint;

  MyPainter() {
    _paint = Paint();
    _paint.style = PaintingStyle.stroke;
    _paint.strokeWidth = 2;
  }

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawColor(Colors.black, BlendMode.color);

    _rect = Rect.fromLTWH(
        size.width / 4, size.height / 4, size.width / 2, size.height / 2);

    _paint.color = Colors.red;
    canvas.drawDashRect(_rect, 3, 3, _paint);

    _paint.color = Colors.yellow;
    canvas.drawDashLine(_rect.topLeft, _rect.bottomRight, 3, 3, _paint);
    canvas.drawDashLine(_rect.bottomLeft, _rect.topRight, 3, 3, _paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

///
/// Canvas扩展函数
/// @Author weitianpeng
/// @Create 2021-3-28
///
extension CanvasExt on Canvas {
  ///绘制虚线
  ///[p1] 起点
  ///[p2] 终点
  ///[dashWidth] 实线宽度
  ///[spaceWidth] 空隙宽度
  void drawDashLine(
    Offset p1,
    Offset p2,
    double dashWidth,
    double spaceWidth,
    Paint paint,
  ) {
    assert(dashWidth > 0);
    assert(spaceWidth > 0);

    double radians;

    if (p1.dx == p2.dx) {
      radians = (p1.dy < p2.dy) ? pi / 2 : pi / -2;
    } else {
      radians = atan2(p2.dy - p1.dy, p2.dx - p1.dx);
    }

    this.save();
    this.translate(p1.dx, p1.dy);
    this.rotate(radians);

    var matrix = Matrix4.identity();
    matrix.translate(p1.dx, p1.dy);
    matrix.rotateZ(radians);
    matrix.invert();

    var endPoint = MatrixUtils.transformPoint(matrix, p2);

    double tmp = 0;
    double length = endPoint.dx;
    double delta;

    while (tmp < length) {
      delta = (tmp + dashWidth < length) ? dashWidth : length - tmp;
      this.drawLine(Offset(tmp, 0), Offset(tmp + delta, 0), paint);
      if (tmp + delta >= length) {
        break;
      }

      tmp = (tmp + dashWidth + spaceWidth < length)
          ? (tmp + dashWidth + spaceWidth)
          : (length);
    }

    this.restore();
  }

  ///绘制虚线
  ///[rect] 矩形
  ///[dashWidth] 实线宽度
  ///[spaceWidth] 空隙宽度
  void drawDashRect(
    Rect rect,
    double dashWidth,
    double spaceWidth,
    Paint paint,
  ) {
    drawDashLine(rect.topLeft, rect.topRight, dashWidth, spaceWidth, paint);
    drawDashLine(rect.topRight, rect.bottomRight, dashWidth, spaceWidth, paint);
    drawDashLine(
        rect.bottomRight, rect.bottomLeft, dashWidth, spaceWidth, paint);
    drawDashLine(rect.bottomLeft, rect.topLeft, dashWidth, spaceWidth, paint);
  }
}

上面使用了 dart 扩展,使用的时候直接敲 canvas. 就可以了,很方便。

.



版权声明:本文为eieihihi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。