Dynamically show or hide widgets in Flutter
In Flutter, you can make your application's user interface more interactive by showing or hiding widgets based on specific conditions. Whether you want to display or hide UI elements in response to user actions, Flutter offers various techniques to achieve this functionality. In this post, we will explore how to dynamically show or hide widgets in your Flutter application, enabling you to create more engaging and flexible user interfaces.
Starting code
We will start with the following code in our main.dart
file:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
State createState() => _MyAppState();
}
class _MyAppState extends State {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dynamic Widget Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Dynamic Widget Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.green,
height: 200,
width: 200,
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {},
child: Text('Toggle Widget'),
),
],
),
),
),
);
}
}
In this code snippet, we create a simple Flutter application where we have a stateful MyApp
widget. Inside our MyApp
widget we display a centered column
widget with a green Container
widget with a height
and width
of 200
, followed by an ElevatedButton
widget. At the moment, the button does not have any functionality. However, in the upcoming sections, we will explore how to add dynamic behavior to this button, enabling us to show or hide the green container based on user interactions.

1. Conditional rendering
The first approach we will take is called conditional rendering. In the code snippet below we have made some changes to our starting code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
State createState() => _MyAppState();
}
class _MyAppState extends State {
bool isVisible = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dynamic Widget Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Dynamic Widget Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (isVisible) Container(
color: Colors.green,
height: 200,
width: 200,
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () => setState(() => isVisible = !isVisible),
child: Text('Toggle Widget'),
),
],
),
),
),
);
}
}
In the above code snippet, we introduce conditional rendering with an if
statement. We use a boolean variable called isVisible
to determine whether the Container
widget should be shown or hidden. When isVisible
is true, the green square is displayed; otherwise, it is hidden.
We achieve the toggle effect by updating the isVisible
variable using the setState
method when the "Toggle Widget" button is pressed. This triggers a rebuild of the widget tree, reflecting the updated visibility status of the green Container
widget.
See the GIF below for the result:

Using curly brackets with anif
statement inside thebuild
method to wrap widgets is not allowed because it returnsSet<void>
, which is not compatible with the expectedWidget
return type. Luckily in Dart we can omit the curly brackets when we only have one condition as we have done in the above code snippet.
1.1 Replacement widget
In the previous implementation, we completely hide our widget. With conditional rendering, it is also possible to show a replacement widget when the original widget is hidden, see the code below:
isVisible
? Container(color: Colors.green, height: 200, width: 200)
: Container(color: Colors.red, height: 200, width: 200),
In this code snippet, we replaced the if
statement with the ternary operator ? :
to show the green Container
widget when isVisible
is true
and the red Container
widget when isVisible
is set to false
, see the GIF below:

2. Using the Visibility widget
In Flutter we also have a dedicated widget to hide widgets. This is the Visibility
widget.
The Visibility
widget has a required property called visible
, which takes a boolean value. If visible
is set to true
, the child widget will be visible; if it is set to false
, the child widget will be hidden.
Other properties of the Visibility
widget are:
maintainState
: If set totrue
, the widget's current status will be kept even when it is hidden. Iffalse
, the status will reset when hidden.maintainAnimation
: When set totrue
, any active animations within the widget will continue running even when it is hidden. Iffalse
, the animations will stop and reset when hidden.maintainSize
: Whentrue
, the widget's size will remain the same when hidden. Iffalse
, the widget will have zero size when hidden.maintainSemantics
: If set totrue
, the accessibility information of the widget will be kept even when it is hidden.maintainInteractivity
: If set totrue
, the widget will still respond to touch and pointer events even when it is hidden.replacement
: An optional widget to show when the main widget is hidden. It allows you to replace the hidden widget with another one.child
(required): The main widget that will be shown or hidden based on the value of thevisible
property.
Now that we understand the Visibility
widget let us go over some of the possible implementations.
2.1 Completely hidden
To completely hide a widget we can wrap our Container
widget with the Visibility
widget:
Visibility(
visible: isVisible,
child: Container(
color: Colors.green,
height: 200,
width: 200,
),
),
In this code snippet, we introduced the Visibility
widget that takes our Container
widget as a child
. We have set the visible
property to our isVisible
variable. The other functionality remains the same, so when we press the button we will see the following:

2.2 Replacement widget
With the Visibility
widget we can also render a replacement widget, see the following code:
Visibility(
replacement: Container(
color: Colors.red,
height: 200,
width: 200,
),
visible: isVisible,
child: Container(
color: Colors.green,
height: 200,
width: 200,
),
),
In this code snippet, we have added the replacement
property to our Visibility
widget. This property allows us to specify a replacement widget to display when the main widget is hidden. In our example, we used a red Container
widget as the replacement.

Using the replacement
property with the Visibility
widget achieves the same thing as the conditional rendering approach we used earlier with the ternary operator. However, I find that using the Visibility
widget makes the code easier to understand. It provides a simpler way to control widget visibility, making the code clearer and easier to work with.
2.3 Prevent Widget Movement
Previously, when we hid the green Container
widget completely, the button would move up because the container's space was removed. To prevent this, we can use additional properties with the Visibility
widget:
Visibility(
maintainSize: true,
maintainAnimation: true,
maintainState : true,
visible: isVisible,
child: Container(
color: Colors.green,
height: 200,
width: 200,
),
),
In this code snippet, we have introduced three properties: maintainSize
, maintainAnimation
, and maintainState
, all set to true
. The maintainSize
property ensures that the Container
widget remains hidden while still occupying its space. The maintainSize
property can only be set to true
whenever the maintainAnimation
and maintainState
are also set to true
.

3. Changing the color to transparent
Another way to hide our widget is by setting its color property to Colors.transparent
. Although this approach may not be used for every widget, it can still be a convenient tool to use in certain scenarios.
Container(
color: isVisible ? Colors.green : Colors.transparent,
height: 200,
width: 200,
),
In this code snippet, we use the isVisible
variable to determine the value of the color property. When isVisible
is false
, we set the color to Colors.transparent
, otherwise, it is set to Colors.green
.
As you can see in the GIF below this approach also prevents the widgets from moving.

Conclusion
Flutter offers various methods to dynamically show or hide widgets, allowing you to create more interactive and flexible user interfaces based on changing conditions or user interactions. No matter which method you pick: conditional rendering, the Visibility widget, or color changes. Each approach has its advantages and can be used depending on specific use cases and requirements.