Анимация в SliverAppBar = ›динамическое изменение размера панели

У меня SliverAppBar с AnimatedContainer внутри. Высота этого анимированного контейнера изменяется во время выполнения, поэтому контейнер анимирует его изменение размера. Моя проблема в том, что expandedHeight моего SliverAppBar исправлен. Но для этого нужно изменить размер аналогично моему анимированному контейнеру.

Есть ли способ установить для SliverAppBar высоту всегда в соответствии с дочерним элементом или чем-то в этом роде? AnimatedContainer не имеет обратного вызова, который дает мне каждое изменение, пока он анимирует изменение размера. Если бы был такой обратный вызов, я мог бы соответственно изменить атрибут expandedHeight SliverAppBar.

Есть идеи, как решить мою проблему? Спасибо!

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
            )
        ]
    )
)
            

Изменить - вот гифка, показывающая, чего я хочу достичь: введите описание изображения здесь


person progNewbie    schedule 23.06.2020    source источник
comment
Думаю, я недавно ответил на аналогичный вопрос ... проверьте, поможет ли это вам stackoverflow.com/questions/62445009/   -  person LonelyWolf    schedule 23.06.2020
comment
@LonelyWolf Я думаю (могу ошибаться), что это что-то другое. AnimatedContainer не запускается при прокрутке чего-либо с полосы прокрутки. Я знаю эти эффекты SliverAppBar.   -  person progNewbie    schedule 23.06.2020
comment
хм ... тогда прошу прощения ... не могли бы вы включить в свой вопрос какое-нибудь видео в формате GIF, чего вы хотите достичь, чтобы лучше понять ваш вопрос   -  person LonelyWolf    schedule 23.06.2020
comment
@LonelyWolf нет причин извиняться. Я добавил гифку, которая показывает, чего я хочу достичь. При нажатии кнопки мой «animatedContainer» расширяется и меняет высоту. Соответственно, расширенныйHeight моего SliverAppBar должен расширяться, как на гифке.   -  person progNewbie    schedule 23.06.2020
comment
Насколько я могу судить по вашему изображению, gif, я вижу, что вы столкнулись с той же проблемой, что и я. Если вы поместите какой-нибудь анимированный виджет в ленту AppBar, то анимация этого виджета будет мешать анимации ленты. У меня была проблема с CircularAvatar, который, по-видимому, имеет встроенную анимацию. Я бы посоветовал вам сделать это без SliverAppBar и использовать анимированный контейнер, как вы, или избавиться от анимированного контейнера в SliverAppBar.   -  person LonelyWolf    schedule 23.06.2020
comment
Кстати, опубликуйте свое решение здесь .. для других ...   -  person LonelyWolf    schedule 23.06.2020


Ответы (1)


Если вы проверите AnimatedContainer docs, они скажут:

Этот класс полезен для создания простых неявных переходов между различными параметрами контейнера с его внутренним AnimationController. Для более сложных анимаций вы, вероятно, захотите использовать подкласс AnimatedWidget, например DecoratedBoxTransition, или использовать свой собственный AnimationController.

Здесь «неявный» означает, что вы не собираетесь управлять анимацией и, следовательно, вы не сможете получить доступ к AnimationController, который позволит вам прослушивать шаги анимации. Для этого вам понадобится что-то вроде AnimatedWidget.

Более глубокий взгляд на AnimationController показывает, что он унаследован от ImplicitlyAnimatedWidget, о чем говорится в документации:

ImplicitlyAnimatedWidgets (и их подклассы) автоматически анимируют изменения в своих свойствах всякий раз, когда они меняются. Для этого они создают и управляют своими собственными внутренними контроллерами AnimationController для управления анимацией. Хотя эти виджеты просты в использовании и не требуют ручного управления жизненным циклом AnimationController, они также несколько ограничены: помимо целевого значения для анимированного свойства, разработчики могут выбрать только продолжительность. и кривая для анимации. Если вам требуется больший контроль над анимацией (например, вы хотите остановить ее где-то посередине), рассмотрите возможность использования AnimatedWidget или одного из его подклассов. Эти виджеты принимают анимацию в качестве аргумента для включения анимации. Это дает разработчику полный контроль над анимацией за счет того, что вам придется вручную управлять базовым AnimationController.

Итак, вам нужно создать объект AnimatedController и передать его AnimatedWidget. Вы можете увидеть пример в документации.

Наконец, чтобы что-то делать на каждом шаге анимации, вам нужно добавить функцию прослушивателя в AnimatedController, используя его метод addListener, что обычно делается в методе initState вашего виджета.

person pposca    schedule 28.07.2020