You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 01:45:01