Search code examples
flutteranimationvisibilityopacity

Flutter Animate Visibility with opacity


The Flutter Visibility Widget allows everything contained within it to be both hidden and disabled. However, I want to animate the opacity as well as invoke visibility. Using the Visibility widget is overriding the animated opacity. This is to be expected based on my knowledge of other languages.

Is there a simple and convenient way to achieve an animated opacity and visibility. IT would make life simpler than setting a timer.

The example below uses a bool of hasAccess using Provider as the state management.

child: Stack(
  children: [

  Visibility(
    visible: hasAccess ? false : true,
    child: AnimatedOpacity(
      duration: Duration(milliseconds: 400),
      opacity: hasAccess ? 0 : 1,
      child: Text('Not logged in'),
  )), 

  Visibility(
    visible: hasAccess ? true : false,
    child: AnimatedOpacity(
      duration: Duration(milliseconds: 400),
      opacity: hasAccess ? 1 : 0,
      child: Text('Is logged in'),
   ),
  ), 
 ],
)

Solution

  • Visibility and Opacity are two entirely different things.

    Opacity can be used to change the opacity of its child. AnimatedOpacity allows for an animation of this and FadeTransition allows for a transition of this. However, opacity simply deals only with opacity. The child is still painted on the screen even if you can't see it. It will still respond to pointer events and it is still taking up computational resources.

    The Visibility class is an amalgamation of various other classes including IgnorePointer. Depending on the settings given, it will either replace the child entirely with a widget that takes up minimal resources and has no content (the default is SizedBox.shrink()) or move it OffScreen or simply prevent pointer events. It will always make it invisible without any animation. It can effectively replace a Widget entirely, move it offscreen or disable pointer events whilst always making the child invisible.

    Using AnimatedOpacity or FadeTransition will allow you to animate the opacity. Once that animation is complete and the child has an opacity of 0, is when to use Visibility. You can find the status of your animation through listeners, timers or any other method you can think of.

    You will find that Widgets like AnimatedOpacity also have callback functions. You could use one of these functions for when the animation is complete. You could create a state called _visible for example as a bool. Then set it to false once the animation of AnimatedOpacity is complete. You would then wrap the child of AnimatedOpacity in the Visibility Widget setting it's property to your _visible state bool.

    Visibility(visibility: _visible, child: <yourChildWidget>);