【问题标题】:Flutter: How to fix "A RenderFlex overflowed by pixels " error?Flutter:如何修复“像素溢出的 RenderFlex”错误?
【发布时间】:2019-08-11 04:25:43
【问题描述】:

我在我的Flutter 应用程序中使用GridView 来显示图像及其标题。请检查以下代码。

import 'package:flutter/material.dart';

import '../common_ui/search_bar.dart';

class PurchaseProductsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return PurchaseProductsUI();
  }
}

class PurchaseProductsUI extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _PurchaseProductUIState();
  }
}

class _PurchaseProductUIState extends State<PurchaseProductsUI> {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return ListView(
      children: <Widget>[
        Container(
          margin: EdgeInsets.all(20),
          child: SearchBar(),
        ),
        Container(
            margin: EdgeInsets.all(20),
            child: GridView.builder(
                physics: ScrollPhysics(), // to disable GridView's scrolling
                shrinkWrap: true,
                itemCount: 20,
                gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 2),
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                      padding: EdgeInsets.all(5), child: _buildImageBoxes());
                })),
      ],
    );
  }

  Widget _buildImageBoxes() {
    return 
   Column(
      children: <Widget>[
        Container(
          child: Image.network("https://picsum.photos/200/300/?random"),
        ),
        Container(
          padding: EdgeInsets.all(10),
          child:  Text("Text"),        )
      ],
    );

  }
}

运行上述代码时出现以下错误和 UI

I/flutter ( 2743): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 2743): The following message was thrown during layout:
I/flutter ( 2743): A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): The overflowing RenderFlex has an orientation of Axis.vertical.
I/flutter ( 2743): The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
I/flutter ( 2743): black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
I/flutter ( 2743): Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the
I/flutter ( 2743): RenderFlex to fit within the available space instead of being sized to their natural size.
I/flutter ( 2743): This is considered an error condition because it indicates that there is content that cannot be
I/flutter ( 2743): seen. If the content is legitimately bigger than the available space, consider clipping it with a
I/flutter ( 2743): ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex,
I/flutter ( 2743): like a ListView.
I/flutter ( 2743): The specific RenderFlex in question is:
I/flutter ( 2743):   RenderFlex#4a1bb OVERFLOWING
I/flutter ( 2743):   creator: Column ← Padding ← Container ← RepaintBoundary-[<14>] ← IndexedSemantics ←
I/flutter ( 2743):   NotificationListener<KeepAliveNotification> ← KeepAlive ← AutomaticKeepAlive ← SliverGrid ←
I/flutter ( 2743):   MediaQuery ← SliverPadding ← ShrinkWrappingViewport ← ⋯
I/flutter ( 2743):   parentData: offset=Offset(5.0, 5.0) (can use size)
I/flutter ( 2743):   constraints: BoxConstraints(w=150.0, h=150.0)
I/flutter ( 2743):   size: Size(150.0, 150.0)
I/flutter ( 2743):   direction: vertical
I/flutter ( 2743):   mainAxisAlignment: start
I/flutter ( 2743):   mainAxisSize: max
I/flutter ( 2743):   crossAxisAlignment: center
I/flutter ( 2743):   verticalDirection: down
I/flutter ( 2743): ◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
I/flutter ( 2743): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
I/flutter ( 2743): Another exception was thrown: A RenderFlex overflowed by 111 pixels on the bottom.
Reloaded 0 of 446 libraries in 1,179ms.

下面是用户界面

我该如何解决这个问题?

【问题讨论】:

    标签: android dart flutter flutter-layout


    【解决方案1】:

    尝试在 _buildImageBoxes() 函数中使用 Expanded 而不是 Container

      Widget _buildImageBoxes() {
        return Column(
          children: <Widget>[
            Expanded(
              child: Image.network("https://picsum.photos/500/500/?random"),
            ),
            Container(
              padding: EdgeInsets.all(10),
              child: Text("Text"),
            )
          ],
        );
      }
    

    【讨论】:

      【解决方案2】:

      Expanded → 计算空间

      ColumnRow 中的ExpandedFlexible 小部件将使Flutter 计算剩余空间并将该空间用于布局。

      不在ExpandedFlexible 中的小部件的布局无论屏幕/约束空间如何


      为什么/如何工作

      ColumnRow 分为两个主要阶段:

      1. Flexible
      2. Flexible 项目(ExpandedFlexible 小部件)

      第一阶段

      Flutter 执行第 1 阶段时没有考虑屏幕大小或任何其他限制。

      Flutter 只是将所有非弹性因子的项目大小相加。

      对于屏幕或其他限制而言,总和太大? → RenderFlex overflowed 异常。

      第二阶段

      带有flex 构造函数参数的小部件是弹性因子项目。

      FlexibleExpanded 小部件。 (Spacer 也是,但没有人使用它。)

      在第 1 阶段之后,所有 flex-factor 小部件的布局考虑到剩余空间


      非弹性布局阶段和弹性因子布局阶段之间的主要区别

      • 非弹性布局 → 不管空间
      • 弹性因子布局→使用剩余空间

      ColumnRow 中,将小部件包装在ExpandedFlexible 中,Flutter 将计算其布局的剩余空间。这将防止问题中出现RenderFlex overflowed 异常,因为每个Image 小部件都会根据空间限制自行调整大小

      但在第 1 阶段,没有空间限制。所以Images 不会调整大小(和溢出)。

      ColumnRow 中的子小部件 包裹在 ExpandedFlexible 中,无论屏幕/约束空间如何,都将以其固有尺寸布局。

      之前

      Space 400
        Column
          Image 150
          Image 150
          Image 150
      

      非弹性图像总和:450。可用空间:400 → Overflowed

      解决方案:使用阶段 2 → 使用计算空间

      之后

      在弹性小部件Expanded 中包装Image,可用高度计算 然后在Expanded(作为约束)和Image 之间共享 调整大小以适应在Expanded 约束内:

      Space 400
        Column
          Expanded 133
            → Image ←
          Expanded 133
            → Image ←
          Expanded 133
            → Image ←
      

      扩展的总和:399。空间:400 → OK

      【讨论】:

        【解决方案3】:
        Widget build(BuildContext context) {
        
            final _screenSize = MediaQuery.of(context).size;
        
            return Container(
              height: _screenSize.height * 0.2,);
        }                                                                                     
        

        MediaQuery.of(context)它对我有用!

        【讨论】:

          【解决方案4】:

          错误(因为键盘):

          您也可以在使用TextField 启动屏幕键盘时遇到此错误,以解决它

          Scaffold(
            resizeToAvoidBottomInset: false, // <-- Set it to false.
            body: SingleChildScrollView(
              child: Column(
                children: [
                  SizedBox(height: 600),
                  TextField(),
                ],
              ),
            ),
          )
          

          错误(无键盘):

          在列/行中为您的孩子使用Expanded/Flexible

          • 使用Expanded

            Column(
              children: [
                Expanded(
                  flex: 1,
                  child: Widget1(),
                ),
                Expanded(
                  flex: 2,
                  child: Widget2(),
                )
              ],
            )
            
          • 使用Flexible

            Row(
              children: [
                Flexible(
                  flex: 1,
                  child: Widget1(),
                ),
                Flexible(
                  flex: 2,
                  child: Widget2(),
                )
              ],
            )
            
          • 给定一个固定的高度:

            Column(
              children: [
                SizedBox(
                  height: 200,
                  child: Widget1(),
                ),
                Expanded(
                  flex: 2,
                  child: Widget2(),
                )
              ],
            )
            

          【讨论】:

            【解决方案5】:

            在您的Image.network 方法中使用fit 属性来减小图像的大小,因为它们更大并且从您的容器中溢出,或者您可以通过它们的heightwidth 属性来放大您的Containers .

            【讨论】:

            • 使用过的 BoxFit.fill、BoxFit.cover,没有任何改变。
            • @PeakGen 将您的 image.network 包装成 Expanded 一切都会好起来的
            • 我可以请我看看这个 fit 属性方法的一些示例代码 - 那个集合在哪里??
            猜你喜欢
            • 2020-02-04
            • 2019-11-26
            • 2021-07-24
            • 2019-05-13
            • 2021-06-21
            • 2021-09-27
            • 2020-06-18
            • 1970-01-01
            • 2021-09-02
            相关资源
            最近更新 更多