Flutter自定义AppBar反向动画异常问题排查求助
问题根源
当你将CustomAppBar作为Scaffold的appBar参数使用时,Scaffold会依赖PreferredSizeWidget的preferredSize属性计算页面整体布局——包括顶部区域高度、body的偏移量等。
切换页面修改height时,CustomAppBar的preferredSize会立刻同步更新为目标高度(90),Scaffold会强制触发全局布局,直接把AppBar的可用高度锁死在新值上。但此时AnimatedContainer的动画还在从260向90过渡,父容器的强制约束会打断动画流程,导致出现先跳变到中间值(你看到的120)、再完成剩余动画的异常。
而把CustomAppBar移到body中时,它脱离了Scaffold对AppBar的特殊布局约束,动画完全由自身的AnimatedContainer控制,因此能正常平滑过渡。
解决办法
方案1:固定PreferredSize为最大高度
让CustomAppBar的preferredSize始终保持首页的最大高度(260),避免Scaffold因高度变化强制布局,动画完全由AnimatedContainer处理:
class CustomAppBar extends StatefulWidget implements PreferredSizeWidget{ double height; String title; Color color; Color textColor; CustomAppBar(this.height, this.title, this.color, this.textColor, {super.key}); @override State<CustomAppBar> createState() => _CustomAppBarState(); @override // 固定为最大高度,不再随widget.height变化 Size get preferredSize => const Size.fromHeight(260); }
注意:这种方式下,Scaffold的body会始终从260高度的位置开始布局,你需要给body添加对应顶部内边距,或者通过Stack调整内容位置,避免被AppBar遮挡。
方案2:将CustomAppBar放入Body
就是你已经验证有效的方式,把自定义AppBar放在body的顶部,完全脱离Scaffold的AppBar布局约束。如果需要保留系统AppBar的特性(比如状态栏适配、返回按钮),可以在自定义AppBar中手动添加这些元素,比如用SafeArea处理状态栏,用IconButton添加返回按钮。
内容的提问来源于stack exchange,提问作者Amine Messabhia

