How to know the size of a widget before painting it?
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
).
Miguel Ruivo
Mobile engineer at Hypnotic. Organizer of Flutter Portugal.
Updated on December 11, 2022Comments
-
Miguel Ruivo over 1 year
I’m trying to use an
AnimatedContainer
for just a simple animation of an expand effect (similar toExpandableTile
) 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 almost 5 yearsMake your own RenderBox
-
Miguel Ruivo almost 5 yearsIs 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 almost 5 yearsThat'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 almost 5 yearsDo you know any good alternative way to achieve such feature? Even going the expensive way, which would be the best in your opinion?
-
-
WebMaster about 3 yearsDo you have alternative solution?
-
Miguel Ruivo about 3 yearsThere 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 about 3 yearsSee stackoverflow.com/q/67056614/6447123 please, we have TextPainter.size for text, Basically there must be similar class for widgets
-
user10033434 over 2 years@MiguelRuivo Hello.. can you share a minimum working code? Thanks.. I'm facing a similar situation