How to make a line dash in Flutter like this?
Create this class:
class DotWidget extends StatelessWidget {
final double totalWidth, dashWidth, emptyWidth, dashHeight;
final Color dashColor;
const DotWidget({
this.totalWidth = 300,
this.dashWidth = 10,
this.emptyWidth = 5,
this.dashHeight = 2,
this.dashColor = Colors.black,
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(
totalWidth ~/ (dashWidth + emptyWidth),
(_) => Container(
width: dashWidth,
height: dashHeight,
color: dashColor,
margin: EdgeInsets.only(left: emptyWidth / 2, right: emptyWidth / 2),
),
),
);
}
}
Usage:
Use it like any other widget
child: DotWidget(
dashColor: Colors.black,
dashHeight: 2,
dashWidth: 100,
)
You should prefer using CustomPainter because it's more performance and suitable for such issues.
class DashLine extends StatelessWidget {
const DashLine({
Key key,
this.color,
this.dashWidth,
this.dashSpace,
this.strokeWidth,
}) : super(key: key);
final Color color;
final double dashWidth;
final double dashSpace;
final double strokeWidth;
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: _DashLinePainter(
color: color,
dashWidth: dashWidth,
dashSpace: dashSpace,
strokeWidth: strokeWidth,
),
);
}
}
class _DashLinePainter extends CustomPainter {
_DashLinePainter({
Color color,
double dashWidth,
double dashSpace,
double strokeWidth,
}) : _color = color ?? Colors.red,
_dashWidth = dashWidth ?? 5.0,
_dashSpace = dashSpace ?? 5.0,
_strokeWidth = strokeWidth ?? 1.0;
final Color _color;
final double _dashWidth;
final double _dashSpace;
final double _strokeWidth;
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = _color
..strokeWidth = _strokeWidth;
var max = size.width;
var startX = 0.0;
while (max >= 0) {
canvas.drawLine(Offset(startX, 0), Offset(startX + _dashWidth, 0), paint);
final space = (_dashSpace + _dashWidth);
startX += space;
max -= space;
}
}
@override
bool shouldRepaint(_DashLinePainter oldDelegate) {
return _color != oldDelegate._color ||
_dashWidth != oldDelegate._dashWidth ||
_dashSpace != oldDelegate._dashSpace ||
_strokeWidth != oldDelegate._strokeWidth;
}
}
Here is the code for horizontal dashed line, like your image. CustomPaint is highly recommended by flutter team for stuff like this. It is fast and efficient for rendering also. You can play with Offset to change the direction.
class MyClass extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: CustomPaint(
painter: MyLinePainter(),
),
);
}
}
class MyLinePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
var max = 100;
var dashWidth, dashSpace = 5;
double startX = 0;
final paint = Paint()..color = Colors.grey;
while (max >= 0) {
canvas.drawLine(Offset(startX, 0), Offset(startX + dashWidth, 0), paint..strokeWidth = 1);
final space = (dashSpace + dashWidth);
startX += space;
max -= space;
}
}
Vertical dashed line:
I modifed maksimr's example:
class DashedLine extends StatelessWidget {
final double height;
final double heightContainer;
final Color color;
const DashedLine({this.height = 3, this.color = Colors.black, this.heightContainer = 70});
@override
Widget build(BuildContext context) {
return Container(
height: heightContainer,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final boxHeight = constraints.constrainHeight();
final dashWidth = 10.0;
final dashHeight = height;
final dashCount = (boxHeight / (2 * dashHeight)).floor();
return Flex(
children: List.generate(dashCount, (_) {
return SizedBox(
width: dashWidth,
height: dashHeight,
child: DecoratedBox(
decoration: BoxDecoration(color: color),
),
);
}),
mainAxisAlignment: MainAxisAlignment.spaceBetween,
direction: Axis.vertical,
);
},
),
);
}
}