How to know the size of a widget before painting it?

639

I end up finding the solution by using the Offstage widget which fits perfectly in this scenario.

Solution

Wrapping the subtree in a Offstage and assigning it a key (can be a GlobalKey), then, before actually rendering it, I can get its height by doing:

  void _getWidgetHeight() {
    if (subtreeHeight == null) {
      RenderBox renderBox = key.currentContext.findRenderObject();
      subtreeHeight = renderBox.size.height;
    }
    setState(() {
      _isOffstage = false;
    });
  }

this way, if you have an AnimatedContainer, for example, and need to animate to its final size, you can have the following:

AnimatedContainer(
        duration: Duration(milliseconds: 250),
        height: subtreeHeight ?? 100.0 // some default size,
      ...
  )

and it will render accordingly.

As a note, make sure the content in your subtree can be inserted inside the Container while it is animating (eg. wrapping the Offstage in a Flexible if you´re using it in a Column or Row).

Share:
639
Miguel Ruivo
Author by

Miguel Ruivo

Mobile engineer at Hypnotic. Organizer of Flutter Portugal.

Updated on December 11, 2022

Comments

  • Miguel Ruivo
    Miguel Ruivo over 1 year

    I’m trying to use an AnimatedContainer for just a simple animation of an expand effect (similar to ExpandableTile) when the user press it.

    My issue is that this container, when expanded, can have either 10.0 height, or 1000.0 (it must be dynamic). Ok, to animate it, it needs to know the height before-hand, makes sense. But how would I know the max height of something before rendering it (I’m going to render Text which can have 1 to N lines)).

    I’ve think in a lot of possibilities, but none seem to fit. Most of the times we get the size from something that is already rendered, from the RenderBox, not the opposite, so this is kind bugging me.

    Thank you in advance!

    • Rémi Rousselet
      Rémi Rousselet almost 5 years
      Make your own RenderBox
    • Miguel Ruivo
      Miguel Ruivo almost 5 years
      Is that necessary for what looks like such a common use case? How creating my own RenderBox would help me? Can you provide a simple example? Ty Rémi.
    • Rémi Rousselet
      Rémi Rousselet almost 5 years
      That's not a common case. Most existing technologies do not offer such feature. The issue is that it requires to layout that element twice. That's expensive
    • Miguel Ruivo
      Miguel Ruivo almost 5 years
      Do you know any good alternative way to achieve such feature? Even going the expensive way, which would be the best in your opinion?
  • WebMaster
    WebMaster about 3 years
    Do you have alternative solution?
  • Miguel Ruivo
    Miguel Ruivo about 3 years
    There is not, AFAIK. You need to always paint the widgets before accessing its size. Offstage makes it possible by inserting the widget in the tree without actually displaying it.
  • WebMaster
    WebMaster about 3 years
    See stackoverflow.com/q/67056614/6447123 please, we have TextPainter.size for text, Basically there must be similar class for widgets
  • user10033434
    user10033434 over 2 years
    @MiguelRuivo Hello.. can you share a minimum working code? Thanks.. I'm facing a similar situation