I need to render my custom object inside of a ListTile with custom painter in order to draw some custom text.
ListTile(
title: CustomPaint(
painter: RowPainter.name(
_titleFontSelected,
_titleFont,
text,
index,
MediaQuery.of(context),
currentRow,
),
),
);
Inside my RowPainter
I draw the text with the font selected.
When the row is too large, it automatically wraps and get drawn outside the given paint size.
void paint(Canvas canvas, Size size)
I like this behavior, but how can I resize the height of my paint area? Because this is a problem since this overlaps the next List row.
I know that the CustomPaint
has a property Size
settable, but I know the text dimension only inside my paint function using the TextPainter getBoxesForSelection
but it's too late.
How can I "resize" my row painter height dynamically if the text wraps?
You cannot dynamically size a custom painter, however, your problem can be solved using a CustomPaint
.
I will first elaborate on the dynamic sizing and then explain how to solve this problem using a constant size.
This is essentially, where CustomPaint
has its limits because it does not provide a way for you to size the painter based on the content.
The proper way of doing this is implementing your own RenderBox
and overriding performLayout
to size your render object based on the contents.
The RenderBox
documentation is quite detailed on this, however, you might still find it difficult to get into it as it is quite different from building widgets.
All of the above should not be needed in your case because you do not have a child
for your custom paint.
You can simply supply the size
parameter to your CustomPaint
and calculate the required height in the parent widget.
You can use a LayoutBuilder
to get the available width:
LayoutBuilder(
builder: (context, constraints) {
final maxWidth = constraints.maxWidth;
...
}
)
Now, you can simply use a TextPainter
to retrieve the required size before even entering your custom paint:
builder: (context, constraints) {
...
final textPainter = TextPainter(
text: TextSpan(
text: 'Your text',
style: yourTextStyle,
),
textDirection: TextDirection.ltr,
);
textPainter.layout(maxWidth: maxWidth); // This will make the size available.
return CustomPaint(
size: textPainter.size,
...
);
}
Now, you can even pass your textPainter
to your custom painter directly instead of passing the style arguments.
Your logic might be a bit more complicated, however, the point is that you can calculate the size before creating the CustomPaint
, which allows you to set the size.
If you need something more complicated, you will likely have to implement your own RenderBox
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With