Flutter中AnimatedSize组件缩小容器尺寸时无动画效果,仅放大时生效
问题原因分析
你遇到的问题核心在于直接强制将子组件高度设为0,导致AnimatedSize无法捕捉到平滑的尺寸变化过程。当你把_height设为0时,Steps组件里的ListView被瞬间压缩到0高度,尺寸跳变过于突兀,AnimatedSize没有机会生成过渡动画帧,所以看起来是直接收起的。
解决方案
我们需要让子组件的尺寸变化是自然的布局变化,而非外部强制设置高度,这样AnimatedSize才能正确监听并生成动画。具体修改如下:
1. 调整Steps组件逻辑
移除Steps中强制设置高度的代码,改为通过控制列表项数量来控制组件高度:
class Steps extends StatelessWidget { const Steps({ Key? key, required this.isExpanded, // 添加展开状态控制参数 }) : super(key: key); final bool isExpanded; @override Widget build(BuildContext context) { return ListView.builder( padding: EdgeInsets.zero, shrinkWrap: true, itemBuilder: (context, index) => Column( children: [ ListTile( dense: true, leading: Text('# ${index + 1}'), title: Text( kRecipeSteps[index], style: TextStyle(fontSize: 22, color: Colors.white), ), ), Divider( color: Colors.white, thickness: 1.0, ), ], ), // 根据展开状态动态控制列表项数量 itemCount: isExpanded ? kRecipeSteps.length : 0); } }
2. 简化主组件结构与逻辑
去掉冗余的_height变量,直接通过_isExpanded状态控制Steps的显示,同时简化AnimatedSize的嵌套层级:
class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override _HomeScreenState createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin { double? screenWidth; double? screenHeight; bool _isExpanded = false; Color _color = Colors.grey.withOpacity(0.75); void _updateSize() { setState(() { _isExpanded = !_isExpanded; }); } @override Widget build(BuildContext context) { screenWidth = MediaQuery.of(context).size.width; screenHeight = MediaQuery.of(context).size.height; return Scaffold( body: Center( child: GestureDetector( onTap: _updateSize, // 简化嵌套,让AnimatedSize直接包裹带样式的容器 child: AnimatedSize( vsync: this, duration: Duration(milliseconds: 500), curve: Curves.easeInOut, // 使用双向平滑曲线优化动画体验 child: Container( padding: EdgeInsets.all(25), decoration: BoxDecoration( color: _color, borderRadius: BorderRadius.circular(20), ), child: Steps(isExpanded: _isExpanded), ), ), ), ), ); } }
为什么这样修改有效?
- 当
_isExpanded为false时,Steps的itemCount变为0,ListView会自然收缩到0高度,这个尺寸变化是布局层面的渐变过程,AnimatedSize能完整捕捉到并生成过渡动画。 - 简化嵌套结构后,约束传递更清晰,避免了多层容器导致的尺寸计算异常。
- 使用
Curves.easeInOut曲线,让放大和缩小动画都更自然流畅,不会出现生硬的加速/减速效果。
内容的提问来源于stack exchange,提问作者who-aditya-nawandar
相关产品推荐
相关产品推荐

