题记
只是一个很简单的绘制虚线的需求,发现前同事写的一个组件,他得方案是通过LayoutBuilder 获取的宽高、然后循环绘制 SizeBox 然后设置背景色...
这个方案,怎么说吧,遇到不定宽高的虚线时,就不好使用了,左侧的虚线是根据右侧项目的高度变化的。
如下图:
所以需要一个可以根据容器情况来绘制的虚线。
我这边推荐的是使用 CustomPainter 通过自定义画笔,可以很好的拿到组件的宽高,然后直接绘制一条虚线即可.
需要注意的是:代码中 CustomPainter内使用Container而不是SizeBox是因为, 如果外层套着 Expand的话SizeBox不会生效的。
完整代码
import 'package:flutter/material.dart';
import 'package:sales_point/const/const_color.dart';
///绘制虚线
class DashLine extends StatelessWidget {
final Color color;
final bool isHorizontal;
final double gap;
final double lineWidth;
final double? width;
final double? height;
const DashLine.horizontal({
super.key,
this.color = ConstColor.colorEBEBEB,
this.gap = 4,
this.lineWidth = 5,
this.width,
this.height = 2,
}) : isHorizontal = true;
const DashLine.vertical({
super.key,
this.color = ConstColor.colorEBEBEB,
this.gap = 4,
this.lineWidth = 5,
this.width = 2,
this.height,
}) : isHorizontal = false;
@override
Widget build(BuildContext context) {
return CustomPaint(
foregroundPainter: DashLinePainter(
color: color,
isHorizontal: isHorizontal,
lineWidth: lineWidth,
gap: gap,
),
child: Container(
width: width,
height: height,
),
);
}
}
/// 为卡片画上一个线条
class DashLinePainter extends CustomPainter {
final Color color;
final bool isHorizontal;
final double gap;
final double lineWidth;
DashLinePainter({
super.repaint,
required this.color,
this.isHorizontal = false,
this.gap = 2,
this.lineWidth = 5,
});
@override
void paint(Canvas canvas, Size size) {
// 创建一个画笔对象,设置颜色和线宽
final drawWidth = isHorizontal ? size.height : size.width;
Paint paint = Paint()
..color = color
..strokeWidth = drawWidth
..style = PaintingStyle.stroke;
// 使用画笔和定义的起点、终点来绘制线条
final x = drawWidth / 2;
if (isHorizontal) {
for (var i = 0.0; i < size.width; i += (lineWidth + gap)) {
final startPosition = Offset(i, x);
final endPosition = Offset(i + lineWidth, x);
canvas.drawLine(startPosition, endPosition, paint);
}
} else {
for (var i = 0.0; i < size.height; i += (lineWidth + gap)) {
final startPosition = Offset(x, i);
final endPosition = Offset(x, i + lineWidth);
canvas.drawLine(startPosition, endPosition, paint);
}
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}