flutter collapsable container

How to show hide and collapse widgets in Flutter

Show hide widgets in Flutter

In Flutter, you can show and hide widgets by changing their visibility property. You can use the Visibility widget to wrap any widget and set the visible property to true or false. If the visible property is set to false, the widget will not be visible. You can also use the Offstage widget, which takes a boolean value and sets the widget to be offstage when the boolean is set to true.

Here is an example of how to use the Visibility widget to show or hide a Text widget:

bool _isVisible = true;

// ...

Column(
  children: [
    ElevatedButton(
      onPressed: () {
        setState(() {
          _isVisible = !_isVisible;
        });
      },
      child: Text('Toggle Visibility'),
    ),
    Visibility(
      visible: _isVisible,
      child: Text('This is a visible text'),
    ),
  ],
)

In this example, a ElevatedButton is used to toggle the _isVisible variable, which controls the visibility of the Text widget.

You can also use the Opacity widget which can be used to fade in and out a widget by controlling its opacity. It takes a property opacity which is a value between 0.0 and 1.0, where 0.0 is completely transparent and 1.0 is completely opaque.

bool _isVisible = true;

// ...

Column(
  children: [
    ElevatedButton(
      onPressed: () {
        setState(() {
          _isVisible = !_isVisible;
        });
      },
      child: Text('Toggle Visibility'),
    ),
    Opacity(
      opacity: _isVisible ? 1.0 : 0.0,
      child: Text('This is a visible text'),
    ),
  ],
)

Alternatively, you can also use the Offstage widget, it takes a boolean property offstage which tells whether the child widget should be visible or not.

bool _isVisible = true;

// ...

Column(
  children: [
    ElevatedButton(
      onPressed: () {
        setState(() {
          _isVisible = !_isVisible;
        });
      },
      child: Text('Toggle Visibility'),
    ),
    Offstage(
      offstage: !_isVisible,
      child: Text('This is a visible text'),
    ),
  ],
)

These are some ways to show or hide widgets in Flutter, you can choose the one that best suits your requirements.

What is the Visibility widget in Flutter, what it is used for and how it works?

The Visibility widget in Flutter is used to control the visibility of a child widget. It takes a visible property, which is a boolean value that determines whether the child widget should be visible or not. When the visible property is set to true, the child widget is visible, and when it is set to false, the child widget is hidden. The hidden widget will still take up the same space in the layout and will be part of the semantic tree, but it won’t be visible to the user.

The Visibility widget can be used in various situations, for example, you can use it to show or hide a loading spinner, a login form, or a snackbar. It can also be used to show or hide different parts of an application based on the user’s interaction with the app, such as a navigation menu or a search bar.

When the visible property changes, the Visibility widget rebuilds its child widget, and the framework takes care of animating the transition between visible and hidden states. However, if you want to have more control over the animation, you can use AnimatedOpacity or AnimatedCrossFade widgets.

It’s important to note that the Visibility widget doesn’t account for the space occupied by hidden widgets, so if you’re using it in a Stack or Positioned widget, other widgets may be affected by the hidden widget’s size. To overcome this limitation, you can use the Offstage widget, which is similar to the Visibility widget but it doesn’t take up space when it is hidden.

What is the Opacity widget in Flutter, what it is used for and how it works?

The Opacity widget in Flutter is used to control the opacity of a child widget. It takes a opacity property, which is a value between 0.0 and 1.0, where 0.0 is completely transparent and 1.0 is completely opaque. The Opacity widget applies an alpha value to the child widget’s entire paint, making it appear more or less transparent.

The Opacity widget can be used in various situations, for example, you can use it to fade in or out a widget, to show or hide a widget by controlling its opacity, or to create a transparent overlay effect. It can also be used in combination with other animations, such as scaling or rotating, to create more complex animations.

When the opacity property changes, the Opacity widget rebuilds its child widget, and the framework takes care of animating the transition between different opacities. However, if you want to have more control over the animation, you can use AnimatedOpacity which is an animated version of the Opacity widget.

It’s important to note that the Opacity widget applies the alpha value to the child widget’s entire paint, including text, borders, and backgrounds. It does not affect the child widget’s layout or hit test behaviour, so it’s suitable for creating transparent overlays but it may not be the best option when you want to hide a widget or change the layout of your interface.

Flutter Opacity widget

Here’s an example of how to use the Opacity widget in a Flutter app:

Column(
children: <Widget>[
Opacity(
opacity: _isVisible ? 1.0 : 0.0,
child: Container(
width: double.infinity,
height: 100,
color: Colors.red,
),
),
ElevatedButton(
child: Text("Toggle Visibility"),
onPressed: () {
setState(() {
_isVisible = !_isVisible;
});
},
),
],
)
flutter opacity widget

In this example, we have a Column that contains an Opacity widget and a ElevatedButton. The Opacity widget wraps a Container widget and has an opacity property that is controlled by a boolean variable _isVisible. When _isVisible is true, the Opacity widget has an opacity of 1.0, making the Container fully visible. When _isVisible is false, the Opacity widget has an opacity of 0.0, making the Container completely transparent.

The ElevatedButton has a child property that is set to a Text widget, and an onPressed property that changes the value of _isVisible when the button is pressed. This changes the opacity of the Container, making it visible or transparent.

The Opacity widget can be used in many different ways in a Flutter app, for example, you can use it to create a fade-in and fade-out animation effect for a splash screen or a loading screen, or to create a transition between different pages in your app. The Opacity widget can also be used to create a ghost button effect, which is a button with low opacity, to indicate that it is disabled.

What is the Offstage widget in Flutter, what it is used for and how it works?

The Offstage widget in Flutter is used to control the visibility of a child widget by removing it from the layout. The Offstage widget takes a offstage property, which is a boolean value that determines whether the child widget should be included in the layout or not. When the offstage property is set to true, the child widget is hidden, and when it is set to false, the child widget is visible.

The Offstage widget can be used in various situations, for example, you can use it to show or hide a widget by removing it from the layout, or to create a sliding animation effect. Unlike the Visibility widget, the Offstage widget doesn’t take up space when it is hidden, so it can be used in a Stack or Positioned widget without affecting other widgets.

When the offstage property changes, the Offstage widget rebuilds its child widget, and the framework takes care of animating the transition between visible and hidden states. However, if you want to have more control over the animation, you can use AnimatedCrossFade which is an animated version of the Offstage widget.

It’s important to note that the Offstage widget doesn’t affect the child widget’s layout or hit test behaviour, so it’s suitable for creating sliding animations but it may not be the best option when you want to create a transparent overlay or change the layout of your interface.

Flutter Offstage widget

Here’s an example of how to use the Offstage widget in a Flutter app:

Column(
children: <Widget>[
Offstage(
offstage: !_isVisible,
child: Container(
width: double.infinity,
height: 100,
color: Colors.red,
),
),
ElevatedButton(
child: Text("Toggle Visibility"),
onPressed: () {
setState(() {
_isVisible = !_isVisible;
});
},
),
],
)
flutter offstage widget

In this example, we have a Column that contains an Offstage widget and a ElevatedButton. The Offstage widget wraps a Container widget and has an offstage property that is controlled by a boolean variable _isVisible. When _isVisible is true, the Offstage widget is visible and the Container is shown, When _isVisible is false, the Offstage widget is invisible and the Container is not shown on the screen.

The ElevatedButton has a child property that is set to a Text widget, and an onPressed property that changes the value of _isVisible when the button is pressed. This changes the visibility of the Container, making it visible or hidden from the screen.

The Offstage widget can be used in many different ways in a Flutter app, for example, you can use it to create a sliding animation effect or to create a transition between different pages in your app. The Offstage widget can also be used to create a loading screen or a splash screen or to hide or show certain elements in your app based on user actions or app state.

Create a collapsable Container in Flutter

You can use the Visibility widget to make a Container collapsable in Flutter.

You can achieve this by setting the visible property of the Visibility widget to a boolean value that controls the visibility of the Container. The Container will be visible when the visible property is set to true and hidden when the visible property is set to false.

Here’s an example of how to use the Visibility widget to make a Container collapsable:

bool _isExpanded = true;

// ...

Column(
  mainAxisAlignment: MainAxisAlignment.start,
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    ElevatedButton(
      onPressed: () {
        setState(() {
          _isExpanded = !_isExpanded;
        });
      },
      child: Text(_isExpanded ? 'Collapse' : 'Expand'),
    ),
    Visibility(
      visible: _isExpanded,
      child: Container(
        height: 100,
        width: double.infinity,
        color: Colors.red,
      ),
    ),
  ],
)
flutter offstage widget

In this example, a ElevatedButton is used to toggle the _isExpanded variable, which controls the visibility of the Container. When the button is pressed, the _isExpanded variable is toggled, and the Visibility widget uses the value of this variable to determine whether the Container should be visible or not.

You can also use the AnimatedContainer and use AnimationController to animate the transition between expanded and collapsed states.

bool _isExpanded = true;

// ...

Column(
  mainAxisAlignment: MainAxisAlignment.start,
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    ElevatedButton(
      onPressed: () {
        setState(() {
          _isExpanded = !_isExpanded;
        });
      },
      child: Text(_isExpanded ? 'Collapse' : 'Expand'),
    ),
    AnimatedContainer(
      duration: Duration(milliseconds: 300),
      curve: Curves.easeInOut,
      height: _isExpanded ? 100 : 0,
      width: double.infinity,
      color: Colors.red,
      child: Text('Collapsable Container'),
    ),
  ],
)

This is a simple example of how to use the Visibility widget to make a Container collapsable in Flutter. You can customize this example to suit your needs by changing the child widget, using different animations, or adding more functionality.

Animations and the Visibility widget in Flutter

You can use animations to make the transition between visible and hidden states more visually appealing when using the Visibility widget.

One way to achieve this is by using the AnimatedContainer widget, which allows you to animate changes to its properties such as size, position, and color. For example, you can use the AnimatedContainer to animate the height of a container when it becomes visible or hidden, giving the impression that the container is sliding up or down.

Another way to achieve this is by using the AnimatedSize widget, which allows you to animate changes to the size of a child widget, giving the impression that the child widget is growing or shrinking.

You can also use AnimatedCrossFade to animate the transition between two child widgets based on their visibility. This is useful when you want to create a fade-in and fade-out animation effect.

What is the Flutter AnimatedContainer widget?

The AnimatedContainer widget in Flutter is a widget that allows you to animate changes to its properties, such as size, position, and color. It works by wrapping a Container widget and automatically animating changes to its properties.

To make the AnimatedContainer widget collapsible, you can use a boolean variable to control the visibility of the container and use the AnimatedContainer widget to animate the transition between the visible and hidden states.

Here’s an example of how to use the AnimatedContainer to make a Container collapsable with a child text:

bool _isExpanded = true;

// ...

Column(
  mainAxisAlignment: MainAxisAlignment.start,
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    ElevatedButton(
      onPressed: () {
        setState(() {
          _isExpanded = !_isExpanded;
        });
      },
      child: Text(_isExpanded ? 'Collapse' : 'Expand'),
    ),
    AnimatedContainer(
        duration: Duration(milliseconds: 300),
        curve: Curves.easeInOut,
        height: _isExpanded ? 100 : 1,
        width: double.infinity,
        color: Colors.red,
        child: Center(
            child: _isExpanded
                ? Text("This is a text")
                : SizedBox()
        )
    ),
  ],
)

In this example, when the _isExpanded variable is true, the AnimatedContainer will have a height of 100 and will show the text “This is a text” when the variable is false the AnimatedContainer will have a height of 1 and will not show the text.

The duration property specifies the amount of time the animation should take to complete. The curve property specifies the easing curve to use for the animation, which determines how the animation progresses over time. The child property is used to specify the child widget that should be rendered inside the AnimatedContainer

What is the Flutter AnimatedSize widget

The AnimatedSize widget in Flutter is a widget that allows you to animate changes to the size of a child widget. It works by wrapping a child widget and automatically animating changes to its width and height properties.

The AnimatedSize widget can be used to create a growing or shrinking animation effect, or to create a sliding animation effect when combined with a Positioned or Stack widget.

The AnimatedSize widget takes a child widget and an optional curve and duration properties. The curve property controls the easing of the animation, and the duration property controls the duration of the animation.

The AnimatedSize widget works by comparing the new size with the previous size, and if it detects any changes, it animates the transition between the two sizes.

It is important to note that, AnimatedSize widget does not have the vsync property, it’s not required because it doesn’t use a AnimationController internally, instead it uses a Animation object which is driven by the AnimationController of the nearest ancestor StatefulWidget.

Here’s an example of how to use the AnimatedSize widget:

AnimatedSize(
    curve: Curves.easeInOut,
    duration: Duration(milliseconds: 300),
    child: Container(
        width: _width,
        height: _height,
        color: Colors.red,
    )
),

In this example, the AnimatedSize has a duration property set to 300 milliseconds and a curve property set to Curves.easeInOut, these properties are used to control the duration and easing of the animation. The child property is set to a Container whose width and height are controlled by _width and _height variables respectively.

You can use the AnimatedSize widget to create different animations, from growing or shrinking animations to sliding animations.

Here’s an example of how to use the AnimatedSize widget to create a collapsible container:

bool _isVisible = true;

AnimatedSize(
    curve: Curves.easeInOut,
    duration: Duration(milliseconds: 300),
    vsync: this,
    child: Container(
        width: double.infinity,
        height: _isVisible ? 100 : 0,
        color: Colors.red,
    )
),

In this example, the AnimatedSize has a duration property set to 300 milliseconds, a curve property set to Curves.easeInOut and vsync property, which is the current state, these properties are used to control the duration and easing of the animation. The child property is set to a Container whose height is controlled by the _isVisible variable. When _isVisible is true, the container’s height is set to 100, and when it’s false, the container’s height is set to 0, making it collapse.

You can use the AnimatedSize widget to create different animations, from growing or shrinking animations to sliding animations.

What is the Flutter AnimatedCrossFade widget?

Here’s an example of how to use the AnimatedCrossFade widget in a Flutter app:

bool _isVisible = true;

Column(
  children: <Widget>[
    AnimatedCrossFade(
      firstChild: Container(
        width: double.infinity,
        height: 50,
        color: Colors.red,
      ),
      secondChild: Container(
        width: double.infinity,
        height: 100,
        color: Colors.blue,
      ),
      crossFadeState: _isVisible
          ? CrossFadeState.showFirst
          : CrossFadeState.showSecond,
      duration: Duration(seconds: 1),
    ),
    ElevatedButton(
      child: Text("Toggle Visibility"),
      onPressed: () {
        setState(() {
          _isVisible = !_isVisible;
        });
      },
    ),
  ],
)
flutter animatedcrossfade widget

In this example, we have a Column that contains an AnimatedCrossFade widget and a ElevatedButton. The AnimatedCrossFade widget has firstChild and secondChild properties that are set to two Container widgets with different colours, red and blue.

The crossFadeState property is controlled by a boolean variable _isVisible, when _isVisible is true it’s set to CrossFadeState.showFirst, this means that the first child will be shown, and when _isVisible is false it’s set to CrossFadeState.showSecond, this means that the second child will be shown.

The duration property of the AnimatedCrossFade is set to 1 second, this controls the duration of the animation effect between the two children.

The RaisedButton has a child property that is set to a Text widget, and an onPressed property that changes the value of _isVisible when the button is pressed. This changes the visibility of the Container, making it visible or hidden from the screen.

AnimatedCrossFade widget is useful when you want to create a smooth transition between two widgets. It can be used to create a fade-in and fade-out animation effect, or to switch between different pages or views in your app.

It’s also important to note that AnimatedCrossFade widget uses the same animation controller as the parent widget, this means that if you are using an AnimatedCrossFade widget inside a StatefulWidget it will stop the animation when the parent widget is removed from the tree.

Flutter expand and collapse the container

Here’s an example of how to create a collapsible container with an IconButton inside that expands and collapses the container:

flutter collapsable container
bool _isExpanded  = true;

Column(
  children: <Widget>[
    AnimatedContainer(
      duration: Duration(milliseconds: 300),
      curve: Curves.easeInOut,
      height: _isExpanded ? 300 : 100,
      width: double.infinity,
      decoration: BoxDecoration(
        color: Colors.red,
        borderRadius: BorderRadius.circular(10),
      ),
      child: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Text(
              "Some text inside the container",
              style: TextStyle(
                fontSize: 18,
                color: Colors.white,
              ),
            ),
          ),
          Align(
            alignment: Alignment.bottomRight,
            child: IconButton(
              icon: Icon(_isExpanded ? Icons.expand_less : Icons.expand_more),
              onPressed: () {
                setState(() {
                  _isExpanded = !_isExpanded;
                });
              },
            ),
          ),
        ],
      ),
    ),
  ],
)

The above code creates a collapsible container using the AnimatedContainer widget. The AnimatedContainer is wrapped inside a Column and it has a child Column which contains some text inside the container and an IconButton.

The AnimatedContainer has a duration property set to 300 milliseconds and a curve property set to Curves.easeInOut, these properties are used to control the duration and easing of the animation. The height property of the AnimatedContainer is controlled by a boolean variable _isExpanded, when _isExpanded is true the container’s height is set to 300, and when it’s false, the container’s height is set to 100, making it collapse.

The IconButton has an icon property that is set to an Icon widget, the icon changes depending on the value of _isExpanded, it’s an expand icon when _isExpanded is false and a collapse icon when _isExpanded is true. The onPressed property of the IconButton changes the value of _isExpanded when the button is pressed and triggers the animation of the AnimatedContainer.

The child of the AnimatedContainer is a Column that contains some text inside the container and an IconButton, This IconButton is aligned to the bottom right of the container and is used to expand or collapse the container.

Overall, when the user presses the IconButton, the state of the _isExpanded variable changes and triggers the animation of the AnimatedContainer, which expands or collapses depending on the value of _isExpanded.

Another example of the Flutter collapsible widget

Here’s an example of a more creative collapsible widget in Flutter:

bool _isExpanded  = true;

Column(
  children: <Widget>[
    GestureDetector(
      onTap: () {
        setState(() {
          _isExpanded = !_isExpanded;
        });
      },
      child: Container(
        decoration: BoxDecoration(
          color: Colors.blue,
          borderRadius: BorderRadius.circular(10),
        ),
        width: double.infinity,
        height: 50,
        child: Stack(
          children: <Widget>[
            Positioned(
              left: 10,
              top: 10,
              child: Icon(
                _isExpanded
                    ? Icons.arrow_drop_up
                    : Icons.arrow_drop_down,
                color: Colors.white,
              ),
            ),
            Center(
              child: Text(
                "Tap to Expand/Collapse",
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 18,
                ),
              ),
            ),
          ],
        ),
      ),
    ),
    AnimatedSize(
      // vsync: this,
      duration: Duration(milliseconds: 300),
      curve: Curves.easeInOut,
      child: Container(
        height: _isExpanded ? 150 : 0,
        width: double.infinity,
        decoration: BoxDecoration(
          color: Colors.red,
          borderRadius: BorderRadius.circular(10),
        ),
        child: Center(
          child: Text(
            "Expanded Content",
            style: TextStyle(
              color: Colors.white,
              fontSize: 18,
            ),
          ),
        ),
      ),
    ),
  ],
)
flutter collapsable widget

In this example, we have a Column that contains a GestureDetector and an AnimatedSize widget. The GestureDetector wraps a Container that has a Stack as its child, this Stack contains an Icon and a Text. The Icon changes its direction depending on the value of _isExpanded, it’s an arrow pointing up when _isExpanded is true and an arrow pointing down when it’s false.

The AnimatedSize widget wraps another Container which contains the expanded content that is shown when the user taps the GestureDetector. The height property of the inner container is controlled by the _isExpanded variable. When _isExpanded is set to true, the height of the inner container is set to 150, making the expanded content visible, and when _isExpanded is set to false, the height is set to 0, making the expanded content not visible.

The AnimatedSize widget also has a duration property set to 300 milliseconds and a curve property set to Curves.easeInOut, these properties are used to control the duration and easing of the animation.

You can also customize the design and add more functionality like adding more content or having a button that can expand and collapse the container.

The GestureDetector is used to detect the user’s tap on the container and toggle the _isExpanded variable, this causes the animation to occur and the container to expand or collapse.