flutter animatedopacity

What is the Flutter AnimatedOpacity widget and how to use it

What is the Flutter AnimatedOpacity widget

The Flutter AnimatedOpacity widget allows you to animate the opacity of a child widget. The opacity is the level of transparency of a widget. When the opacity is set to 1, the widget is fully visible, and when it is set to 0, the widget is fully transparent and not visible.

AnimatedOpacity takes two main arguments:

  • opacity: The opacity you want to animate to. It’s a double value between 0 and 1.
  • duration: The duration of the animation. It’s a Duration object that you can use to specify how long the animation should take.

When you use AnimatedOpacity, it animates the opacity of the child widget from its current value to the value you specify in the opacity argument. For example, if you set opacity to 0.5, the child widget will animate from its current opacity to 0.5 over the specified duration.

Here’s an example of how you could use AnimatedOpacity to animate the opacity of a container:

AnimatedOpacity(
    duration: Duration(seconds: 1),
    opacity: _visible ? 1.0 : 0.0,
    child: Container(
        width: 100,
        height: 100,
        color: Colors.red,
    ),
),

In the above example, when _visible is true, the container’s opacity will animate from 0 to 1 over 1 second. When _visible is false, the container’s opacity will animate from 1 to 0 over 1 second.

It’s a simple way to add visual interest to your app and make it more engaging. It’s also a useful tool for creating animations that reveal or hide a widget, as it allows you to animate the widget’s visibility.

Where the Flutter AnimatedOpacity widget can be used

The AnimatedOpacity widget can be used in various places within a Flutter app where you want to animate the transition of an element’s opacity. Here are a few examples of where you might use the AnimatedOpacity widget:

  • To create a button or other interactive element that fades in and out when tapped
  • To create a loading animation that fades in and out
  • To create a transition between different pages or screens in your app
  • To animate the transition between different elements within a container or other layout widget
  • To create an animation effect when displaying a dialogue or other overlay on the screen
  • To create a transition effect for items in a list or other scrolling container
  • To create an animation effect for images, text, or other widgets when the user interacts with them

The AnimatedOpacity widget can be used in combination with other animation widgets such as AnimatedContainer, AnimatedCrossFade, AnimatedPositioned and many others to create more complex and dynamic animations.

How to use the AnimatedOpacity widget in Flutter

Here’s an example of how you could create a button to toggle the visibility of an AnimatedOpacity widget:

bool _isVisible = true;

@override
Widget build(BuildContext context) {

  return Scaffold(
    appBar: AppBar(
      title: Text('flutterassets.com'),
    ),
    body:
    Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          AnimatedOpacity(
            duration: Duration(milliseconds: 500),
            opacity: _isVisible ? 1 : 0,
            child: Container(
              width: 100,
              height: 100,
              color: Colors.red,
            ),
          ),
          SizedBox(height: 10),
          ElevatedButton(
            onPressed: () {
              setState(() {
                _isVisible = !_isVisible;
              });
            },
            child: Text("Toggle Visibility"),
          ),
        ],
      ),
    )
  );
}

In the code above, the AnimatedOpacity is used to animate the visibility of a red Container widget. The AnimatedOpacity widget takes two main arguments, duration and opacity.

duration is a Duration object that specifies how long the animation should take. In this example, the duration is set to 500 milliseconds, which means the animation will take half a second to complete.

opacity is a double value between 0 and 1 that represents the level of transparency of the child widget. If the opacity is set to 0, the widget is fully transparent and not visible. If the opacity is set to 1, the widget is fully visible. In this example, the opacity is controlled by the _isVisible state variable. When _isVisible is true, the opacity is set to 1, making the Container fully visible, and when _isVisible is false, the opacity is set to 0, making the Container fully transparent.

The AnimatedOpacity widget has only one child, which is the Container widget. The Container widget has a width and height of 100 pixels and a red colour.

The AnimatedOpacity widget is wrapped in a Column widget, which is centred on the screen using the Center widget. The Column widget contains the AnimatedOpacity widget and a RaisedButton widget. The RaisedButton widget has a child property of Text("Toggle Visibility") and an onPressed callback that toggles the value of _isVisible between true and false when the button is pressed.

When the RaisedButton is pressed, the onPressed callback is executed, which calls the setState function, which triggers the build method to be executed again. As a result, the AnimatedOpacity widget re-renders with the updated value of _isVisible. If _isVisible is now false, the AnimatedOpacity will animate the opacity of the Container from 1 to 0 over the specified duration (500 milliseconds), making the container disappear gradually. If _isVisible is now true, the AnimatedOpacity will animate the opacity of the Container from 0 to 1 over the specified duration (500 milliseconds), making the container appear gradually. This allows the user to toggle the visibility of the container by tapping on the button.

Toggle two images with AnimatedOpacity in Flutter

Here’s an example of how you could use the AnimatedOpacity widget to toggle the opacity of two Container widgets with different decoration images, stacked one over the other, triggered by tapping on the containers:

bool _isContainer1Visible = true;
bool _isContainer2Visible = true;

@override
Widget build(BuildContext context) {

final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;

return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body:
Center(
child: Stack(
children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
_isContainer1Visible = !_isContainer1Visible;
});
},
child: AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: _isContainer1Visible ? 1 : 0,
child: Container(
width: screenWidth/3,
height: screenHeight/3,
padding: EdgeInsets.all(6),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage("https://picsum.photos/250?image=9"),
fit: BoxFit.cover,
),
),
),
),
),
GestureDetector(
onTap: () {
setState(() {
_isContainer2Visible = !_isContainer2Visible;
});
},
child: AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: _isContainer2Visible ? 1 : 0,
child: Container(
width: screenWidth/3,
height: screenHeight/3,
padding: EdgeInsets.all(6),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage("https://picsum.photos/250?image=10"),
fit: BoxFit.cover,
),
),
),
),
),
],
),
)
);
}

The above code uses the AnimatedOpacity widget to toggle the visibility of two Container widgets, stacked one over the other when the containers are tapped. The code defines a MyApp class, which is a StatefulWidget, and a corresponding _MyAppState class, which is the state for the MyApp widget.

The build method of the _MyAppState class is where the widgets are built and arranged on the screen. It starts by getting the screen height and width using MediaQuery.of(context).size.height and MediaQuery.of(context).size.width respectively. Then it returns a Scaffold widget, which is the root of the app’s visual structure and it contains a Stack widget. The Stack widget allows you to position multiple widgets on top of each other.

Then, the code defines two GestureDetector widgets, which are used to detect when the containers are tapped. The onTap callback of each GestureDetector toggles the visibility of the corresponding container by changing the value of _isContainer1Visible and _isContainer2Visible variables and calling setState, which causes the widgets to rebuild and apply the new opacity value. Each GestureDetector widget has an AnimatedOpacity widget as a child.

The AnimatedOpacity widget is used to animate the transition between different opacity values of the container. The duration argument is set to 500 milliseconds, so the animation takes half a second to complete. The opacity argument is controlled by the

You can rebuild the code above and use only one bool variable to control the visibility of both containers. You can do this by using the bool variable to determine which container should be visible, and then use the AnimatedOpacity widget to animate the transition between the two containers.

Here’s an example of how you can modify the code to use only one bool variable:

bool _isContainerVisible = false;

@override
Widget build(BuildContext context) {

final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;

return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body:
Center(
child: GestureDetector(
onTap: () {
setState(() {
_isContainerVisible = !_isContainerVisible;
});
},
child: Stack(
children: <Widget>[
AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: _isContainerVisible ? 0 : 1,
child: Container(
width: screenWidth / 3,
height: screenHeight / 3,
padding: EdgeInsets.all(6),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage("https://picsum.photos/250?image=9"),
fit: BoxFit.cover,
),
),
),
),
AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: _isContainerVisible ? 1 : 0,
child: Container(
width: screenWidth / 3,
height: screenHeight / 3,
padding: EdgeInsets.all(6),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage("https://picsum.photos/250?image=10"),
fit: BoxFit.cover,
),
),
),
),
],
),
),
)
);
}

In this example, I removed the GestureDetector widgets and wrapped the Stack widget with a single GestureDetector widget. The onTap callback of the GestureDetector toggles the value of the _isContainerVisible variable and calls setState, which causes the widgets to rebuild and apply the new opacity values.

The AnimatedOpacity widgets use the _isContainerVisible variable to determine the opacity value for each container. When _isContainerVisible is false, the first container has an opacity of 1 and the second container has an opacity of 0, so the first container is visible and the second one is not. When _isContainerVisible is true, the first container has an opacity of 0 and the second container has an opacity of 1, so the second container is visible and the first one is not.

As the user taps on the containers the _isContainerVisible variable will toggle its value between true and false, which will make the containers to animate their opacity and change which one is visible. This way, the user can toggle the visibility of the two containers using only one variable.

Two image Toggle custom widget with AnimatedOpacity in Flutter

Here is an example of how you can create a custom StatelessWidget class called MyImageOpacity:

class MyImageOpacity extends StatelessWidget {
final String imageOne;
final String imageTwo;
final bool imageVisible;
final VoidCallback onPressed;

MyImageOpacity({
required this.imageOne,
required this.imageTwo,
required this.imageVisible,
required this.onPressed,
});

@override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return GestureDetector(
onTap: onPressed,
child: Stack(
children: <Widget>[
AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: imageVisible ? 0 : 1,
child: Container(
width: screenWidth / 3,
height: screenHeight / 3,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(imageOne),
fit: BoxFit.cover,
),
),
),
),
AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: imageVisible ? 1 : 0,
child: Container(
width: screenWidth / 3,
height: screenHeight / 3,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(imageTwo),
fit: BoxFit.cover,
),
),
),
),
],
),
);
}
}

The MyImageOpacity class takes in three required properties: imageOne, imageTwo, and imageVisible. The imageOne and imageTwo properties are used to set the URLs for the first and second network images, respectively. The imageVisible property is a bool value that determines which image is visible.

You can use the MyImageOpacity class to create a row of 3 widgets by wrapping it in a Row widget and passing different values to the properties. Here’s an example:

Row(
  children: <Widget>[
    MyImageOpacity(
      imageOne: "https://picsum.photos/250?image=9",
      imageTwo: "https://picsum.photos/250?image=10",
      imageVisible: _isFirstVisible,
    ),
    MyImageOpacity(
      imageOne: "https://picsum.photos/250?image=11",
      imageTwo: "https://picsum.photos/250?image=12",
      imageVisible: _isSecondVisible,
    ),
    MyImageOpacity(
      imageOne: "https://picsum.photos/250?image=13",
      imageTwo: "https://picsum.photos/250?image=14",
      imageVisible: _
isThirdVisible,
    ),
  ],
)

In this example, I created 3 instances of the `MyImageOpacity` widget, each with its own set of image URLs and a separate `bool` variable to control the visibility of the images. The `Row` widget arranges the widgets horizontally on the screen.

It’s important to note that since the `MyImageOpacity` class is stateless, the `setState` method will not work in the `onTap` callback, it would need to be passed down from the parent widget, where the state is kept. The `imageVisible` variable would be passed as a callback function that updates the variable from the parent widget.

Creating a Row with Custom Image Toggling Widget in Flutter

Here is an example of how you can combine the two code examples to create a Flutter app that uses the custom MyImageOpacity widget to create a row of 3 image containers that toggle their visibility when tapped:

flutter animatedopacity
import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatefulWidget {

@override
_MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {

@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {

bool _isFirstVisible = true;
bool _isSecondVisible = true;
bool _isThirdVisible = true;

@override
Widget build(BuildContext context) {

return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body:
Center(
child: Row(
children: <Widget>[
MyImageOpacity(
imageOne: "https://picsum.photos/250?image=9",
imageTwo: "https://picsum.photos/250?image=10",
imageVisible: _isFirstVisible,
onPressed: () {
setState(() {
_isFirstVisible = !_isFirstVisible;
});
},
),
MyImageOpacity(
imageOne: "https://picsum.photos/250?image=11",
imageTwo: "https://picsum.photos/250?image=12",
imageVisible: _isSecondVisible,
onPressed: () {
setState(() {
_isSecondVisible = !_isSecondVisible;
});
},
),
MyImageOpacity(
imageOne: "https://picsum.photos/250?image=13",
imageTwo: "https://picsum.photos/250?image=14",
imageVisible: _isThirdVisible,
onPressed: () {
setState(() {
_isThirdVisible = !_isThirdVisible;
});
},
),
],
),
),
);
}
}

class MyImageOpacity extends StatelessWidget {
final String imageOne;
final String imageTwo;
final bool imageVisible;
final VoidCallback onPressed;

MyImageOpacity({
required this.imageOne,
required this.imageTwo,
required this.imageVisible,
required this.onPressed,
});

@override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return GestureDetector(
onTap: onPressed,
child: Stack(
children: <Widget>[
AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: imageVisible ? 0 : 1,
child: Container(
width: screenWidth / 3,
height: screenHeight / 3,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(imageOne),
fit: BoxFit.cover,
),
),
),
),
AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: imageVisible ? 1 : 0,
child: Container(
width: screenWidth / 3,
height: screenHeight / 3,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(imageTwo),
fit: BoxFit.cover,
),
),
),
),
],
),
);
}
}

The above code creates a Flutter app that has a custom widget called MyImageOpacity. This widget takes in 3 properties: imageOne, imageTwo, and imageVisible. imageOne and imageTwo are used to set the URLs for the first and second network images, respectively. imageVisible is a boolean variable that determines which image is visible.

MyImageOpacity widget uses AnimatedOpacity to animate the transition between the two images, which makes the opacity of one image to change to 0 when the other image’s opacity is 1. The MyApp class uses the MyImageOpacity widget to create a row of 3 image containers. Each container has its own set of image URLs and its own imageVisible variable to control the visibility of the images.

When user taps on any of the container the onPressed callback is executed and the value of the respective imageVisible variable is toggled. This causes the state to rebuild and the widgets to update the opacity accordingly. This way the user can toggle the visibility of the two images by tapping on the container.