1

I'm working on a CustomPainter widget that receives a List<Widget> as an argument. I would like to know the size of each of my Widget so I can adjust my paint. The List<Widget> will be a user-selected List so I can't use GlobalKeys here.

I watched some answers on StackOverflow and articles on the subject but every time the answer seems not adapted to my problem.

class MyPainter extends CustomPainter {
  final List<Widget> myWidgetList;

  MyPainter({
    this.myWidgetList,
  });

  @override
  void paint(Canvas canvas, Size size) {

    for (var item in myWidgetList) {
      // print my widget height.
    }
    ...
  }
}
BLKKKBVSIK
  • 3,128
  • 2
  • 13
  • 33
  • Are widgets inside the list the same height? – Artur Sikora Nov 13 '21 at 19:43
  • @ArturSikora not necessarily, that's why I need to adjust my CustomPainter depending on the `List` – BLKKKBVSIK Nov 13 '21 at 19:48
  • 1
    I think each widget need to be render to get the size no? – mario francois Nov 13 '21 at 20:53
  • 1
    @mariofrancois yeah I agree. Pretty sure you have to wait for the layout phase to complete to find the height of a widget. But if you pass a specific height parameter to each widget then you could just use that – PatrickMahomes Nov 13 '21 at 21:05
  • As others have said, you can only get the height of a widget after the layout phase. Consider a `Container()` in your widget list - what is its height? It's impossible to know, as its height depends on the constraints available and its child. – hacker1024 Nov 14 '21 at 02:45

1 Answers1

1

Since I couldn't get the size of my widget before the rendering, I wrapped every widget in my List<Widget> into another widget that will use GlobalKey and then get access to the size of each of my widget with Context.

It's not a perfect solution but it's the best I could find so far.

class SubtaskWrapper extends StatelessWidget {
  final Widget child;
  final Function onChange;
  final SubTasksViewModel model;

  SubtaskWrapper({
    Key? key,
    required this.onChange,
    required this.model,
    required this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    SchedulerBinding.instance!.addPostFrameCallback(postFrameCallback);

    return Container(
      key: widgetKey,
      child: child,
    );
  }

  GlobalKey widgetKey = GlobalKey();
  Size? oldSize;

  void postFrameCallback(_) {
    BuildContext? context = widgetKey.currentContext;
    if (context == null) return;

    Size? newSize = context.size;
    if (oldSize == newSize) return;

    oldSize = newSize;
    onChange(newSize, model);
  }
}
BLKKKBVSIK
  • 3,128
  • 2
  • 13
  • 33