Last active
November 30, 2023 14:52
-
-
Save ookami-kb/6ac06fb364d4b3a11e1de920a5a38a87 to your computer and use it in GitHub Desktop.
DashedRow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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