Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

animated opacity and hiding the widget so its not clickable

I'm using AnimatedOpacity to hide a the navbar based on a scroll event. I'm specifically having trouble making it animate in and out well, while also making the widget not clickable.

In order to hide my widget and prevent it from being clicked, I conditionally rendering the my CustomNavBar() component or Container() based on the visible state. However, this cuts my animation abruptly when i fade out. It works fading in, however.

AnimatedOpacity(
  opacity: _isVisible ? 1.0 : 0.0,
  duration: Duration(milliseconds: 300),
  child: _isVisible
    ? CustomNavBar()
    : Container(),
)

This is expected, since the component literally is not existing when _isVisible is false. That kills the whole animation. How do I get around this?

Thanks

like image 290
wei Avatar asked Oct 21 '19 20:10

wei


2 Answers

There may be other ways to do this but you could use two variables for opacity and visibility. Make use of the AnimatedWidget's onEnd callback to change visibility. Also, you may want to use the Visibility widget for this. It lets you even maintain the child's state if you want.

/// somewhere outside of build in a StatefulWidget
bool _isVisible = true;
bool _isOpaque = true;


/// within the build method
AnimatedOpacity(
  opacity: _isOpaque ? 1.0 : 0.0,
  onEnd: (){
    if(!_isOpaque)
      setState((){
        _isVisible = false;
      });
  },
  child: Visibility(
    child: child,
    visible: _isVisible,
  ),
);


//then in some method to toggle the state...
setState((){
  if(!_isVisible){
    _isVisible = true;
    _isOpaque = true;
  }
  else{
    _isOpaque = false;
  }
})

Come to think of it, you also have AnimatedSwitcher which is a LOT easier to do this. I will leave the above code for reference to the onEnd callback. Also, if maintaining state in the child widget is important then the above code would be better suited since you have that option. If it's not important then switch-away.

AnimatedSwitcher(
   child: _isVisible ? child : SizedBox.shrink(),
)
like image 195
Adrian Murray Avatar answered Oct 06 '22 01:10

Adrian Murray


IgnorePointer(
    child: AnimatedOpacity(
        child: child,
        opacity: visible ? 1.0 : 0.0,
        duration: const Duration(milliseconds: 200),
    ),
    ignoring: !visible,
)

This is working for me like a charm. Basically, it says "ignore hit testing while child is invisible.

like image 20
Anis Alibegić Avatar answered Oct 06 '22 00:10

Anis Alibegić