Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Custom Painter

hello I have created a widget that extends CustomPainter. The problem is when the paint method is called the Size parameter width and height fields are always 0,0 I am not sure how to fix this. Any thoughts would be greatly appreciated. Here's the widget. Thank you!!

class Box extends CustomPainter {
  double _top = 0.0;
  double _left = 0.0;
  double _width = 0.0;
  double _height = 0.0;
  String _text;

  Box(this._top, this._left, this._width, this._height, this._text);

  @override
  void paint(Canvas canvas, Size size) {
   canvas.drawRect(
      new Rect.fromLTWH(_left, _top, _width, _height),
      new Paint()
        ..style = PaintingStyle.stroke
        ..strokeWidth = 2.0
        ..color = Colors.blue // new Color(0xFF0099FF),
  );
}

 @override
 bool shouldRepaint(Box oldDelegate) {
  return false;
 }
}

and using it as such:

new Positioned(
      left: 0.0,
      top: 0.0,
      child: new Container(
          child:new CustomPaint(
          painter: new Box(block.boundingBox.top.toDouble(), block.boundingBox.left.toDouble(),
              block.boundingBox.width.toDouble(), block.boundingBox.height.toDouble(),
              block.text)
      ))
  )

Thank you again for nay ideas you may have!

like image 200
user1026498 Avatar asked Aug 16 '18 14:08

user1026498


People also ask

How do I create a custom painter in Flutter?

A widget that provides a canvas on which to draw during the paint phase. :To paint in Flutter you can use the CustomPaint widget which basically takes size of its parent if not given the child . The CustomPainter subclass overrides two methods: paint() and shouldRepaint() .

How do I use canvas in Flutter?

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.


1 Answers

A bit more code would be helpful but I think I can give an adequate explanation with what you have done here.

I assume that your Positioned is in a stack, and that the stack has a size due to another element in the stack (or due to being placed in a widget that gives it a size). For example, if the stack is in a SizedBox, Container (with size specified), or similar, it will have a size. Whereas if it's in a Center, it sizes itself based on its children.

In the case where the stack is sized by its children, it determines how big it is based on the biggest of the non-positioned children i.e. those that aren't wrapped in a Positioned or that are wrapped in a Positioned but the positioned doesn't define any of left, right, top, right, width, or height.

So back to your problem - if we assume the stack has a size, then your widget is being placed at the top left. However, as written none of the widgets under your Positioned actually specify their own size - you haven't set the size for the Container or the CustomPaint.

So what you need to do is actually specify how big you want your CustomPaint to be. If you know a specific width/height, you can specify that in the Container or in the CustomPaint's size. If you don't but rather want it to stretch to the size of the stack, you could simply remove the Positioned widget, or define both left/right and/or top/bottom. Or you could do a combination of a specified height or width + offset from sizes of you want. The last thing is that the CustomPaint may still decide to size itself to zero even if the widget outside is the right size. If that's the case, you need to pass in a size (I'm moderately sure that if you pass in Size.infinite it will expand to fill its parent).

The last thing is that I'm not sure what you're doing with your CustomPainter, but it seems like it could be wrong. If all you're doing is trying to paint a square, use the size that's passed into the painter rather than parameters (I'm guessing you're trying to do this to get around the issue you're seeing with size being zero though).

For example, if you're trying to simply draw a rectangle filling the entire painting area, use this:

canvas.drawRect(Offset.zero & size, Paint().....);

If you pass things in however, you need to make sure you're not drawing outside the bounds of the custom painter. From the CustomPaint docs:

The painters are expected to paint within a rectangle starting at the origin and encompassing a region of the given size. (If the painters paint outside those bounds, there might be insufficient memory allocated to rasterize the painting commands and the resulting behavior is undefined.)

like image 121
rmtmckenzie Avatar answered Oct 06 '22 21:10

rmtmckenzie