Widget Hide and Seek: A guide to managing Flutter widget’s visibility
In Flutter, hiding a widget is very easy.
Let’s say you want to hide MyWidget
in this layout when condition
is false
All you have to do is:
However, things get a little more complicated when you notice that if MyWidget
is a StatefulWidget
, it’s State
will be recreated each time MyWidget
is shown. Or the fact that MyWidget
size would shrink to 0 and crumble your layouts. What should you do if you want to get MyWidget
size to do some calculation while it is hidden?
Let’s look at some widgets that handle these use cases:
Visibility
Hide a widget with Visibility
Visibility
will show/hide the child based on the visible
value.
By default, Visibility
will remove the child from the subtree when it’s hidden, which sucks since it’s the same as the first example. So we will use these fields to customize its behavior:
maintainState
: maintain the States in the child widget when it’s hidden.maintainAnimation
: maintain the animations within the child widget when it’s hidden.maintainSize
: maintain the child widget space when it’s hidden.maintainInteractivity
: allow the widget to be interactive when it’s hidden.
These options will pretty much suffice all the use cases you need such as:
- Keeping the child’s
State
but hide the child completely. You can also get the child’s size while it’s hidden.
- Let the child occupy space in the layout but prevent users from interacting.
- Let the child occupy space in the layout and allow users to interact.
Visiblity
also offers the replacement
attribute which acts as a placeholder for when your child widget is hidden and none of the maintain__
fields are enabled.
A few notes:
- All of the
maintain__
fields arefalse
by default. - These fields must be enabled in the ascending order. E.q: If
maintainSize
istrue
thenmaintainAnimation
andmaintainState
must also betrue
. - Dynamically changing these fields may cause a recreation of the
States
in the child widget.
Opacity
This widget will decide to paint it’s child or not based on the opacity
value.
The child will stay in the widget tree only not painted so it’s State
won’t be recreated. It will still take up space and has interactivity.
This is the equivalent of:
You can animate the transition using AnimatedOpacity
or a custom AnimationController
.
The best use case for Opacity
is when you want to perform some animations showing/hiding a widget, otherwise, you are better off with Visibility
since it has better customizations.
Offstage
This widget will hide the child based on the offstage
value.
The child won’t take up any space or have any interactivity but you can still get the child size.
This is the equivalent of:
Conclusion
As you can see, Visibility
covers pretty much all cases except animations. So make sure to keep it in mind the next time you want to hide a widget
Have fun Fluttering!