Flutter中Visibility的maintainSize不生效?如何实现保状态的全屏组件切换
问题原因分析
你遇到的maintainSize未生效的核心原因是:Visibility组件的尺寸控制仅作用于自身,无法修改其父组件的布局约束。
你的代码中两个Visibility外层都包裹了Expanded,而Column下的多个Expanded会默认按flex权重(默认都是1)平分父容器的垂直空间,不管Expanded的子组件是否可见,Expanded自身都会占据对应的空间份额,所以两个容器永远各占50%高度,和Visibility的配置无关。
可行解决方案
你要求不能用条件渲染同时保留组件状态,有两种最简单的实现方式:
方案1:联动Expanded的flex属性
将不可见组件对应的Expanded的flex值设为0,即可让其不占用布局空间,可见组件的flex设为1占满全屏:
Widget _toggleWidget() => GestureDetector( onTap: () { setState(() => redblue = redblue == 0 ? 1 : 0); }, child: Column(children: [ Expanded( flex: redblue == 0 ? 1 : 0, child: Visibility( visible: redblue == 0, maintainState: true, child: Container(color: Colors.blue[600]), ), ), Expanded( flex: redblue == 1 ? 1 : 0, child: Visibility( visible: redblue == 1, maintainState: true, child: Container(color: Colors.red[600]), ), ) ]), );
方案2:使用IndexedStack(更推荐)
Flutter内置的IndexedStack组件天生支持保留所有子组件的状态,仅显示对应index的子组件,完全符合你的需求,代码更简洁:
Widget _toggleWidget() => GestureDetector( onTap: () { setState(() => redblue = redblue == 0 ? 1 : 0); }, child: IndexedStack( index: redblue, children: [ Container(color: Colors.blue[600]), Container(color: Colors.red[600]), ], ), );
另外你提到的AutomaticKeepAliveClientMixin也是可行方案,更适合在PageView、TabBarView等可滑动切换的容器中保留子组件状态的场景。
内容的提问来源于stack exchange,提问作者jola
相关产品推荐
相关产品推荐

