【问题标题】:Popup with GridView that covers part of the screen带有覆盖部分屏幕的 GridView 弹出窗口
【发布时间】:2021-04-25 16:20:39
【问题描述】:

更新:我想通了。看我的回答below

我将GridView 呈现为一个弹出路由,它会产生

下面的代码

class GridPopup extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Align(
        alignment: Alignment.bottomCenter,
        child: Container(
          color: Colors.blue,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              RaisedButton(
                child: Text('Close popup'),
                onPressed: () => Navigator.of(context).pop(),
              ),
              // Expanded(
              //   child: GridView.count(
              GridView.count(
                crossAxisCount: 5,
                crossAxisSpacing: 2.0,
                mainAxisSpacing: 2.0,
                childAspectRatio: 1.0,
                shrinkWrap: true,
                children: List.generate(
                  25,
                  (index) => Container(color: Colors.green),
                ),
              ),
              // ),
            ],
          ),
        ),
      ),
    );
  }
}

此处提供的代码:gistdartpad

问题是当GridView中的项目数增加时,会溢出

可以通过用Expanded 包裹GridView 来修复它,但是弹出窗口总是覆盖整个屏幕

我可以在不使用Expanded 小部件且不指定大小的情况下修复溢出吗?换句话说,我希望弹出窗口的高度尽可能小(项目少时少,项目多时多),同时仍包含 GridView,以免溢出。

【问题讨论】:

    标签: flutter dart flutter-layout


    【解决方案1】:

    我想通了。 GridView 应该用Flexible 小部件而不是Expanded 包裹。其余代码保持不变。

    ...
    Flexible(
      child: GridView.count(
        crossAxisCount: 5,
        crossAxisSpacing: 2.0,
        mainAxisSpacing: 2.0,
        childAspectRatio: 1.0,
        shrinkWrap: true,
        children: List.generate(
          25,
          (index) => Container(color: Colors.green),
        ),
      ),
    ),
    ...
    

    更新了gistdartpad

    【讨论】:

      【解决方案2】:

      [![在此处输入图片描述][1]][1]您需要提供scrollDirection功能并且需要将shrinkWrap设为false。你需要覆盖我们的一半。

      class GridPopup extends StatelessWidget {
      int countContainer = 35;
      @override
      Widget build(BuildContext context) {
      double heightPopup = MediaQuery.of(context).size.height *
                  (((countContainer / 5).toDouble()) / 10) >
              MediaQuery.of(context).size.height
          ? MediaQuery.of(context).size.height
          : MediaQuery.of(context).size.height *
              ((((countContainer / 5) + 1) / 10));
      
      print(MediaQuery.of(context).size.height.toString());
      print("heightPopup" + heightPopup.toString());
      return SafeArea(
        child: Align(
          alignment: Alignment.bottomCenter,
          child: Container(
            height: heightPopup,
            color: Colors.blue,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Container(
                  child: RaisedButton(
                    child: Text('Close popup'),
                    onPressed: () => Navigator.of(context).pop(),
                  ),
                ),
      
                Expanded(
                  child: GridView.count(
                    crossAxisCount: 5,
                    crossAxisSpacing: 2.0,
                    mainAxisSpacing: 2.0,
                    childAspectRatio: 1.0,
                    scrollDirection: Axis.vertical,
                    children: List.generate(
                      countContainer,
                      (index) => Container(color: Colors.green),
                    ),
                  ),
                ),
                // ),
              ],
            ),
          ),
         ),
       );
      }
      }
      

      【讨论】:

      • 我不希望弹出窗口的大小受到限制。我可以通过将其限制为特定大小来解决我的问题,而无需更改 shrinkWrap 并且不使用 scrollDirection
      • 你不能。但你可以这样做。我正在更新答案。这是你想要的最合乎逻辑的一个。在我看来
      • 其实可以的。应该使用Flexible 而不是Expanded。我已经回答了我自己的问题 - 检查我的answer。我还包括一个飞镖垫,可以显示差异
      【解决方案3】:

      将 GripPop 更改为,删除 mainAxisSize: MainAxisSize.min 和 shrinkWrap: true:

        void _presentGridPopup(BuildContext context){
          showModalBottomSheet(
              context: context,
              isScrollControlled: true,
              builder: (context) {
                return FractionallySizedBox(
                  heightFactor: 0.8,
                  child: GridPopup(),
                );
              });
        }
      
          class GridPopup extends StatelessWidget {
            @override
            Widget build(BuildContext context) {
              return SafeArea(
                child: Align(
                  alignment: Alignment.bottomCenter,
                  child: Container(
                    color: Colors.blue,
                    child: Column(
                      children: [
                        RaisedButton(
                          child: Text('Close popup'),
                          onPressed: () => Navigator.of(context).pop(),
                        ),
                        Expanded(
                          child: GridView.count(
                            crossAxisCount: 5,
                            crossAxisSpacing: 2.0,
                            mainAxisSpacing: 2.0,
                            childAspectRatio: 1.0,
                            children: List.generate(
                              100,
                              (index) => Container(color: Colors.green),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              );
            }
          }
      

      【讨论】:

      • 不。获取A RenderFlex overflowed by 982 pixels on the bottom. shrinkWrap: trueMainAxisSize.min 背后的想法是呈现一个不覆盖整个屏幕的弹出窗口...
      • 那么你应该在这种情况下使用 showModalBottomSheet 更好,更新答案
      • 不完全。 showModalBottomSheet 覆盖屏幕的固定部分。我希望弹出高度根据其内容而变化。您可以在此dartpad 中查看您的建议
      猜你喜欢
      • 2014-06-29
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多