简体   繁体   中英

Flutter: How to fix "A RenderFlex overflowed by pixels " error?

I am using GridView in my Flutter app to display images and their titles. Please check the below code.

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"),        )
      ],
    );

  }
}

I get the following error and UI when I run the above code

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.

Below is the UI

在此处输入图片说明

How can I solve this?

try to use Expanded instead of Container in _buildImageBoxes() function

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

Expanded → Calculated Space

Expanded or Flexible widgets in Column or Row will make Flutter calculate remaining space & use that space for layout.

Widgets not in Expanded or Flexible are laid out regardless of screen/constraint space .


Why / How this works

Column and Row are laid out in two main phases:

  1. non- Flexible items
  2. Flexible items ( Expanded and Flexible widgets)

Phase 1

Flutter does Phase 1 without screen size or any other constraint in mind.

Flutter just adds all non-flex-factor item sizes together.

Sum too big for screen or other constraint? RenderFlex overflowed exception.

Phase 2

Widgets with flex constructor argument are flex-factor items.

ie Flexible or Expanded widgets. ( Spacer too, but no one uses it.)

After Phase 1, any flex-factor widgets are laid out with remaining space in mind .


Key difference between non-flexible and flex-factor layout phases:

  • non-flex layout → regardless of space
  • flex-factor layout → uses remaining space

Inside Column or Row , wrapping widgets in Expanded or Flexible , Flutter will calculate remaining space for their layout. This would prevent a RenderFlex overflowed exception in the question since each Image widget will size itself to space constraints .

But during Phase 1, there are no space constraints . So the Images aren't resized (and overflow).

Children widgets inside Column or Row not wrapped in Expanded or Flexible will be laid out at their intrinsic size, regardless of screen/constraint space.

Before

Space 400
  Column
    Image 150
    Image 150
    Image 150

Sum non-flex Images: 450. Space available: 400 → Overflowed

Solution : use Phase 2 → use calculated space

After

Wrapping Image in flex widget Expanded , height available is calculated then shared among Expanded (as constraints) and Image is resized to fit inside Expanded constraints:

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

Sum flex Expandeds: 399. Space: 400 → OK

Widget build(BuildContext context) {

    final _screenSize = MediaQuery.of(context).size;

    return Container(
      height: _screenSize.height * 0.2,);
}                                                                                     

MediaQuery.of(context) It worked for me to use!

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

Error (because of keyboard):

You can also run into this error while using a TextField which launches on-screen keyboard, to solve it set

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

Error (without keyboard):

Use Expanded/Flexible for your children in Column/Row.

  • Using Expanded :

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

     Row( children: [ Flexible( flex: 1, child: Widget1(), ), Flexible( flex: 2, child: Widget2(), ) ], )
  • Giving a fixed height:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM