【问题标题】:Why doesn't Flutter widget Visibility's maintainSize prop work for me?为什么 Flutter 小部件 Visibility 的维护大小属性对我不起作用?
【发布时间】:2021-11-12 03:08:40
【问题描述】:

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

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

我希望下面的代码能够实现这一点,因为我在 Visibility 上设置了 maintainSize=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]),
            ),
          )
        ]),
      );

【问题讨论】:

    标签: flutter dart flutter-layout flutter-widget


    【解决方案1】:

    你把两个VisibiltyExpanded 包裹在一个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),
        );
      }
    }
    

    【讨论】:

    • 由于条件渲染不维护未渲染组件的状态,不幸的是,这不是我的选择。
    【解决方案2】:
    ...extends StatefulWidget {
    bool redblue = true;
    ...
    }
    extends State<YourClass> {
    ...
    _toggleWidget()
    ...
    }
    
    Widget _toggleWidget() => GestureDetector(
        onTap: () {
          if (widget.redblue == true)
            setState(() => widget.redblue = false);
          else if (widget.redblue == false) setState(() => widget.redblue = true);
        },
        child: Column(children: [
          Opacity(
            opacity: widget.redblue == true ? 1.0 : 0.0,
            child: Container(width: 400, height: 100, color: Colors.blue[600]),
          ),
          Opacity(
            opacity: widget.redblue == false ? 1.0 : 0.0,
            child: Container(width: 400, height: 100, color: Colors.red[600]),
          )
        ]),
      );
    

    【讨论】:

    • 与我发布的代码 sn-p 的结果相同。
    • 然后尝试摆脱 Expanded
    • 不,不起作用
    • 检查编辑的代码
    • 如果您希望它们在同一个地方使用Stack 而不是Column,但所有这些都可以通过仅将更改转移到颜色来完成
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 2019-04-26
    • 2012-11-25
    • 2021-09-16
    • 2020-02-28
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多