Skip to content

Instantly share code, notes, and snippets.

@ookami-kb
Last active November 30, 2023 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ookami-kb/6ac06fb364d4b3a11e1de920a5a38a87 to your computer and use it in GitHub Desktop.
Save ookami-kb/6ac06fb364d4b3a11e1de920a5a38a87 to your computer and use it in GitHub Desktop.
DashedRow
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: Scaffold(
body: Center(
child: DashedRow(
text: 'This is some probably long text',
trailing: Checkbox(value: true, onChanged: (_) {}),
),
),
),
);
}
}
class DashedRow extends SingleChildRenderObjectWidget {
const DashedRow({super.key, required this.text, Widget? trailing})
: super(child: trailing);
final String text;
@override
RenderObject createRenderObject(BuildContext context) =>
RenderDashedRow(text: text);
@override
void updateRenderObject(BuildContext context, RenderDashedRow renderObject) {
renderObject.text = text;
}
}
class RenderDashedRow extends RenderBox
with RenderObjectWithChildMixin<RenderBox> {
RenderDashedRow({required String text})
: _text = text,
_textPainter = TextPainter(
maxLines: 1,
textDirection: TextDirection.ltr,
ellipsis: '...',
text: TextSpan(
text: text,
style: const TextStyle(color: Colors.black),
),
);
final TextPainter _textPainter;
final Paint _dashPaint = Paint()
..color = Colors.black
..strokeWidth = 1
..style = PaintingStyle.stroke;
Size _dashSize = Size.zero;
String _text;
String get text => _text;
set text(String value) {
if (_text == value) return;
_text = value;
_textPainter.text = TextSpan(
text: value,
style: const TextStyle(color: Colors.black),
);
markNeedsLayout();
}
@override
void performLayout() {
child?.layout(constraints, parentUsesSize: true);
final trailingSize = child?.size ?? Size.zero;
_textPainter.layout(maxWidth: constraints.maxWidth - trailingSize.width);
final dashSize = Size(
constraints.maxWidth - _textPainter.width - trailingSize.width,
1,
);
_dashSize = dashSize.width >= 10 ? dashSize : Size.zero;
size = Size(
constraints.maxWidth,
max(_textPainter.height, trailingSize.height),
);
}
@override
void paint(PaintingContext context, Offset offset) {
_textPainter.paint(
context.canvas,
offset + Offset(0, (size.height - _textPainter.size.height) / 2),
);
_drawDashedLine(
context.canvas,
offset + Offset(_textPainter.width, (size.height - _dashSize.height) / 2),
_dashSize,
);
child?.paint(
context,
offset +
Offset(
size.width - child!.size.width,
(size.height - child!.size.height) / 2,
),
);
}
void _drawDashedLine(Canvas canvas, Offset offset, Size size) {
const int dashWidth = 4;
const int dashSpace = 4;
double startX = 0;
while (startX < size.width) {
canvas.drawLine(
offset + Offset(startX, 0),
offset + Offset(startX + dashWidth, 0),
_dashPaint,
);
startX += dashWidth + dashSpace;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment