I got a SliverAppBar with an AnimatedContainer inside. The height of this animated container changes on runtime, so the container animates its resizing. My problem is, that the expandedHeight of my SliverAppBar is fix. But this needs to resize analog to my animated Container.

Is there a way to set the SliverAppBar to "height is always according to child" or something like that? The AnimatedContainer has no callback which gives me every change while it animates the resizing. If there would be such a callback I could change the expandedHeight attribute of the SliverAppBar accordingly by myself.

Any idea how to fix my problem? Thanks!

return SliverAppBar(
      elevation: 0,
      snap: true,
      pinned: false,
      floating: true,
      forceElevated: false,
      primary: false,
      automaticallyImplyLeading: false,
      backgroundColor: Colors.white,
      expandedHeight: _eHeight,
      flexibleSpace: Column(children: <Widget>[
        AnimatedContainer(
            onEnd: onTopBarsAnimationEnd,
            height: _trending
                ? _tabBarHeight: _tabBarHeight + topicsHeight,
            duration: Duration(milliseconds: 800),
            curve: Curves.fastOutSlowIn,
            child: // some child
            )
        ]
    )
)

Edit - Here is a gif showing what I want to achieve: enter image description here


Solution 1: pposca

If you inspect AnimatedContainer docs, they say:

This class is useful for generating simple implicit transitions between different parameters to Container with its internal AnimationController. For more complex animations, you'll likely want to use a subclass of AnimatedWidget such as the DecoratedBoxTransition or use your own AnimationController.

Here, 'implicit' means you are not going to control the animation and thus, you are not going to be able to access the AnimationController class that is going to allow you to listen the animation steps. To do it, you are going to need something like AnimatedWidget.

A deeper look into AnimationController reveals it inherits from ImplicitlyAnimatedWidget, which docs say:

ImplicitlyAnimatedWidgets (and their subclasses) automatically animate changes in their properties whenever they change. For this, they create and manage their own internal AnimationControllers to power the animation. While these widgets are simple to use and don't require you to manually manage the lifecycle of an AnimationController, they are also somewhat limited: Besides the target value for the animated property, developers can only chose a duration and curve for the animation. If you require more control over the animation (e.g. you want to stop it somewhere in the middle), consider using a AnimatedWidget or one of its subclasses. These widget take an Animation as an argument to power the animation. This gives the developer full control over the animation at the cost of requiring you to manually manage the underlying AnimationController.

So what you need is to create your AnimatedController object and pass it to an AnimatedWidget. You can see an example in the docs.

Finally, to do something in each animation step, you need to add a listener function to the AnimatedController using its method addListener, what usually is done in the initState method of your widget.