I’m working on an app that can display a "no connection" widget at the top of it when internet is lost. Since my app doesn’t have a "forehead" part per-se, I’m just adding a widget to the tree (to be more precise, I make an appBar appear).
The problem with that solution is that even with the use of ShowUpAnimation
, when the widget appears, the space is taken instantly. This displaces all the elements brutally, it looks pretty choppy and bad. Here’s what it looks like, pardon my literal french:
I’m looking for a solution to this problem that would allow me to ease-in that widget with a transition that pushes the rest of the screen down gently over a certain duration so it looks smoother. Additionally, my current solution doesn’t handle widget exit, it just disappears which is even more jarring.
Thanks in advance !
Code:
How the app bar is called in the Scaffold:
appBar: !viewModel.hasConnection
? const PreferredSize(
preferredSize: Size.fromHeight(35),
child: NoConnectionAppBar(),
) : null
viewModel.hasConnection
is automatically updated with a Stream.
How the app bar is implemented in the class:
Widget build(BuildContext context) {
return ShowUpAnimation(
curve: Curves.linear,
offset: -0.5,
child: AppBar(...)
);
}
3
Answers
Here is my answer, there were two cases:
In the first case, the bar needed to take some vertical space on the screen. So I removed the appBar, and instead wrapped the
Scaffold
in an Expanded and then in Column. In the controller, I defined a variable namedtopBarWidget
. When the controller gets created, we initialized that widget to either my no connection bar or to a 0 height SizedBox. We also hook up this logic to the function that handles connection detection. Finally, I added anAnimatedSize
widget on top of the Column with that topBarWidget as the child. Works great, make sure the Column is wrapped in a safe area though.In the second case, I actually found I didn't need my widget to take vertical space, so I just added the same logic in the controller to define a topBarWidget. Then, I wrapped that topBarWidget in an
AnimatedSwitcher
with a transition builder that used aSizeTransition
.You will find the code the result. Thanks @dstreissi for putting me on the right tracks.
1 - Taking up vertical space
2 - Stacking up on the Z-axis
Notice how I put the ScrollView inside the Stack so that my noConnection message would stay on top of the screen even when scrolling down.
If you want to stick with the
AppBar
you should consider using something likeSliverAppBar
it has theexpandedHeight
property where you can set its height and change it on event.Keep in mind that
SliverAppBar
should be put inside scrollview withslivers
property. For example —CustomScrollView
More information about:
SliverAppBar (official)
CustomScrollView (official)
unofficial guide which you might find helpful
You can also use an
AnimatedContainer
instead theAppBar
and place it above all other Widgets. This gives the advantage that the height can be animated, so the other Widgets are sliding down with the space theAnimatedContainer
uses.more information see here: AnimatedContainer