首页 > 解决方案 > 为什么 Flutter 小部件 Visibility 的维护大小属性对我不起作用?

问题描述

编辑 我最终通过使用 AutomaticKeepAliveClientMixin 解决了这个问题,它允许我将小部件移出屏幕并保持状态。我仍然不清楚 Visibility.maintainSize:false 是如何工作的,但现在不急于理解。 结束编辑

我尝试通过单击屏幕在两个小部件(一个红色,一个蓝色容器)之间切换。我想要的行为是红色容器应覆盖整个屏幕,然后单击,然后蓝色容器覆盖整个屏幕,依此类推。

我希望下面的代码能够实现这一点,因为我在 Visibility 上有维护Size=false。然而这不起作用,蓝色的总是占屏幕高度的 50%,红色的总是占 50%,与它们的可见性无关,我无法让可见的占 100%。

我想了解为什么 maintainSize 不能按我期望的方式工作(即,使用 maintainSize=false 我希望小部件获得 0 宽度/高度,而另一个扩展至全屏)

由于这不起作用,我该怎么做才能获得想要的行为(不使用带有 if-case 的条件渲染,因为我希望保持渲染状态)

  Widget _toggleWidget() => GestureDetector(
        onTap: () {
          if (redblue == 0)
            setState(() => redblue = 1);
          else if (redblue == 1) setState(() => redblue = 0);
        },
        child: Column(children: [
          Expanded(
            child: Visibility(
              visible: (redblue == 0),
              maintainSize: false,
              maintainState: true,
              child: Container(color: Colors.blue[600]),
            ),
          ),
          Expanded(
            child: Visibility(
              visible: (redblue == 1),
              maintainSize: false,
              maintainState: true,
              child: Container(color: Colors.red[600]),
            ),
          )
        ]),
      );

标签: flutterdartflutter-layoutflutter-widget

解决方案


你把两个Visibilty包裹Expanded在一个里面Column ,你会得到正常的行为,即使它不可见,每个都会占据高度的 50%

如果你想让它占据整个高度,就这样做

GestureDetector(
      onTap: () {
        if (redblue == 0)
          setState(() => redblue = 1);
        else if (redblue == 1) setState(() => redblue = 0);
      },
      child:
      (redblue == 0)?
      Container(color: Colors.blue[600])
      : Container(color: Colors.red[600])

或者你可以这样做


class SwitchColor extends StatefulWidget {
  const SwitchColor({Key key}) : super(key: key);

  @override
  _SwitchColorState createState() => _SwitchColorState();
}

class _SwitchColorState extends State<SwitchColor> {
  Color color = Colors.red[600];

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        if (color == Colors.red[600])
          setState(() => color = Colors.blue[600]);
        else
          setState(() => color = Colors.red[600]);
      },
      child: Container(color: color),
    );
  }
}

推荐阅读