1

In the code below, a row of two 300x300 boxes (_Box) wrapped with FittedBox shrinks to fit in the screen. As a result, each box becomes smaller than 300x300.

However, if I get the width of a box in the build() method of _Box using RenderBox.size and LayoutBuilder(), the obtained size is 300.0 and Infinity respectively.

How can I get the actual displayed size?

I'd like to get it inside the _Box class, without it getting passed from the parent.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: FittedBox(
            child: Row(
              children: <Widget>[
                _Box(Colors.red),
                _Box(Colors.orange),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _Box extends StatelessWidget {
  const _Box(this.color);

  final Color color;

  @override
  Widget build(BuildContext context) {
    RenderBox renderBox = context.findRenderObject();
    print(renderBox?.size?.width);  // 300.0

    return LayoutBuilder(
      builder: (_, constraints) {
        print(constraints.maxWidth);  // Infinity

        return Container(
          width: 300,
          height: 300,
          color: color,
        );
      },
    );
  }
}
kaboc
  • 734
  • 1
  • 4
  • 21
  • 1
    Does this answer your question? [How to get a height of a Widget?](https://stackoverflow.com/questions/49307677/how-to-get-a-height-of-a-widget) – Kirill Matrosov Apr 20 '20 at 07:05
  • @kaboc,please check the below solution and let me know in case of concern – Ravindra Kushwaha Apr 20 '20 at 07:20
  • @KirillMatrosov Agh, I've read the answer several months ago but wasn't aware that it could help this time. Thanks. I'll have a look and see if it really works for my case too. – kaboc Apr 20 '20 at 07:54
  • @KirillMatrosov With the same approach, I got `300.0` unfortunately. – kaboc Apr 20 '20 at 08:57

1 Answers1

1

The Flutter constraints object is used to limit how large or small a widget can be rendered, and is usually never really used to get the current size of the widget.

The renderBox.size object is of Size class, and as a result it has both renderBox.size.width and renderBox.size.height as defined getters. Note that these values can only be set once the layout phase of the current view is over: see the findRenderObject() docs page.

This means that you will have to avoid calling findRenderObject() from the build() method. Instead you will have to define a callback function that must execute after the layout process is complete. You can do this using that have widgets that have callback functions like onTap or onSelected. How you implement this and finally get the actual layout size by running the callback function is totally dependent on your use case.

Further recommended reading:

  1. DevelopPaper - Sample code for getting the width and height of screen and widget in Flutter
  2. Flutter on Github - How to get a height of a widget? #16061
  3. Rémi Rousselet's amazing answer explaining his workaround (using an Overlay widget)
Blend3rman
  • 147
  • 12
  • Thanks. I'm conscious about the timing when `renderBox.size.width` is set, which is why I've used `?.` like `renderBox?.size?.width`. I'll read through the linked pages, but can you elaborate how it can actually be achieved? Your answer itself does not give a quick solution for other developers, although I think it contains important information and is helpful even if not the exact answer. – kaboc Apr 20 '20 at 08:11