12

In my Flutter application, I want to connect two arbitrary boxes with a line.
The example shows two MyBoxes in a GridView.

MyBoxes

I want to swipe from MyBox on the left to MyBox on the right and draw a line in the space between them to show the connection.
However, I couldn't find a way to draw lines beyond the widget border.

Is there a way to do this with drawing tricks like CustomPainter, or with changes to the widget's structure?

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
Msyk
  • 662
  • 5
  • 14

1 Answers1

25

I thought that this might be a nice challenge, so I just created a minimum viable example using CustomPainter. Personally, I would always use a custom RenderObject using LeafRenderObjectWidget and RenderBox, however, CustomPainter's are supposed to be easier, which is why I will use it for this example.

The basic idea is having a Stack that contains both your boxes and the CustomPainter, which allows you to draw beyond the constraints of any single widget. In my example, I do not straighten the lines and do not ensure that they connect two boxes, however, you could easily add this by supplying GlobalKey's to your boxes, storing these keys in a global list (e.g. in an InheritedWidget or Provider) and then applying some logic to the positions returned by (globalKey.currentContext.findRenderObject() as RenderBox).localToGlobal(Offset.zero). You can also access the size of your boxes like this using globalKey.currentContext.size.
This, however, would be a bit too much for an answer, which is why I will only share code for the basic context of drawing lines between two widgets:

Source code as a Gist

Illustration

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
  • Thank you for your wonderful idea and knowledge. The combination of `Stack` and `CustomPainter` is very useful to me. I want to draw a line using the location of MyBox, so I'm currently trying to use `GlobalKey` to access the location information. I will mark this answer as soon as we succeed. (I am currently dealing with the error of `Duplicate GlobalKey`.) – Msyk Jul 23 '19 at 10:52
  • 1
    @Msyk Right, as every `MyBox` should be unique, you will have to make the `GlobalKey` unique (otherwise you would not be able to get a distinct widget from your `GlobalKey`). You could e.g. use indexes to differentiate between different boxes. – creativecreatorormaybenot Jul 23 '19 at 14:28
  • 1
    I'm Successful. I saved the Indices of the concatenated MyBox in `InheritsWidget` and drew the line by calculating the Grid size and coordinates from `GlobalKey` given to `GridView`. and, I also learned how Flutter works with `Key` and I fully understood the structure. Thank you very much! – Msyk Jul 24 '19 at 08:18
  • @Mysk A complete sample code would be much appreciated. Can you please share the code in github or somewhere please? I am having difficult time to get the widget at the drag start position and drag end position of the line. If somehow I was able to find the position of those widgets then I could draw a line connecting them. – Shuji Feb 28 '21 at 07:56
  • @creativecreatorormaybenot Can you please share the code too? I can't resist to upvote this answer but on the other side I feel it's half an answer. – Shuji Feb 28 '21 at 07:58
  • @Shuji Here you go: https://gist.github.com/creativecreatorormaybenot/a984d3a64f9ce5362cd31fe6bb585d43 – creativecreatorormaybenot Feb 28 '21 at 11:44
  • @creativecreatorormaybenot This is the same code that you have shared in your answer. Actually I am having difficult time to get the widget at the drag start position and drag end position of the line. If somehow I was able to find the position of those widgets then I could draw a line connecting them. – Shuji Feb 28 '21 at 12:09