The documentation for CustomPainter's paint method says, "To paint text on a Canvas
, use a TextPainter
". So within my MyCustomPainter
's paint method I have the following:
TextSpan span = new TextSpan(text: 'Yrfc'); TextPainter tp = new TextPainter(text: span, textAlign: TextAlign.left); tp.layout(); tp.paint(canvas, new Offset(5.0, 5.0));
I've tried a variety of offsets (Offset.zero, Offset.infinite, new Offset(10.0, 10.0)
but I never am able to see the text painted on the screen.
To paint in Flutter you use the CustomPaint widget. The CustomPaint widget takes a CustomPainter object as a parameter. In that class you have to override the paint method, which gives you a canvas that you can paint on. Here is the code to draw the text in the image above.
To use a TextPainter, follow these steps: Create a TextSpan tree and pass it to the TextPainter constructor. Call layout to prepare the paragraph. Call paint as often as desired to paint the paragraph.
Use \n for paragraphs, like this: Text('Hello,\n\nhow are you?')
Like an artist's canvas is a physical surface to draw on, a Canvas in Flutter is a virtual surface for drawing. But unlike a regular art canvas, you can't paint on the Flutter canvas with physical brushes. Flutter Canvas uses a two-point (x and y) coordinate system to determine the position of a point on the screen.
I found the answer as I was typing up this question but I've been wrestling with it for a while now, so posting in case it helps anyone else.
What solved it was changing the TextSpan line to:
TextSpan span = new TextSpan(style: new TextStyle(color: Colors.grey[600]), text: 'Yrfc');
Apparently it was either drawing the text invisibly or as white (background) color since I hadn't made my color choice explicit.
To paint in Flutter you use the CustomPaint
widget. The CustomPaint
widget takes a CustomPainter
object as a parameter. In that class you have to override the paint
method, which gives you a canvas that you can paint on. Here is the code to draw the text in the image above.
@override void paint(Canvas canvas, Size size) { final textStyle = TextStyle( color: Colors.black, fontSize: 30, ); final textSpan = TextSpan( text: 'Hello, world.', style: textStyle, ); final textPainter = TextPainter( text: textSpan, textDirection: TextDirection.ltr, ); textPainter.layout( minWidth: 0, maxWidth: size.width, ); final xCenter = (size.width - textPainter.width) / 2; final yCenter = (size.height - textPainter.height) / 2; final offset = Offset(xCenter, yCenter); textPainter.paint(canvas, offset); }
ltr
stands for left-to-right, which languages like English use. The other option is rtl
(right-to-left), which languages like Arabic and Hebrew use. This helps to reduce bugs when the code is used in language contexts that developers were not thinking about.Here is the main.dart code so that you can see it in context.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: HomeWidget(), ), ); } } class HomeWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: CustomPaint( // <-- CustomPaint widget size: Size(300, 300), painter: MyPainter(), ), ); } } class MyPainter extends CustomPainter { // <-- CustomPainter class @override void paint(Canvas canvas, Size size) { // <-- Insert your painting code here. } @override bool shouldRepaint(CustomPainter old) { return false; } }
See this article for my fuller answer.
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