Flutter绘制虚线的方法

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. 就可以了,很方便。

 

 

 

.

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Flutter绘制虚线可以使用 `CustomPaint` 和 `Path` 绘制。 下面是一个绘制虚线的示例代码: ```dart import 'dart:ui'; import 'package:flutter/material.dart'; class DashedLine extends StatelessWidget { final double dashedWidth; final double dashedHeight; final Color color; const DashedLine({ Key key, @required this.dashedWidth, @required this.dashedHeight, this.color = Colors.grey, }) : super(key: key); @override Widget build(BuildContext context) { return CustomPaint( painter: _DashedLinePainter( dashedWidth: dashedWidth, dashedHeight: dashedHeight, color: color, ), ); } } class _DashedLinePainter extends CustomPainter { final double dashedWidth; final double dashedHeight; final Color color; _DashedLinePainter({ @required this.dashedWidth, @required this.dashedHeight, @required this.color, }); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = color ..strokeWidth = dashedHeight ..style = PaintingStyle.stroke ..strokeCap = StrokeCap.round; final path = Path(); double startX = 0.0; double endX = dashedWidth; while (endX < size.width) { path.moveTo(startX, dashedHeight / 2); path.lineTo(endX, dashedHeight / 2); startX += dashedWidth * 2; endX += dashedWidth * 2; } canvas.drawPath(path, paint); } @override bool shouldRepaint(_DashedLinePainter oldDelegate) { return oldDelegate.dashedWidth != dashedWidth || oldDelegate.dashedHeight != dashedHeight || oldDelegate.color != color; } } ``` 使用方式: ```dart DashedLine( dashedWidth: 5, dashedHeight: 1, color: Colors.grey, ) ``` 其中,`dashedWidth` 表示虚线的宽度,`dashedHeight` 表示虚线的高度,`color` 表示虚线的颜色。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值