簡體   English   中英

Flutter:如何修復“像素溢出的 RenderFlex”錯誤?

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

我在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.

下面是用戶界面

在此處輸入圖片說明

我該如何解決這個問題?

嘗試在 _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"),
        )
      ],
    );
  }

Expanded →計算空間

ColumnRow ExpandedFlexible小部件將使 Flutter 計算剩余空間並將該空間用於布局。

不在ExpandedFlexible中的小部件的布局與屏幕/約束空間無關


為什么/這是如何工作的

ColumnRow分為兩個主要階段:

  1. Flexible物品
  2. Flexible項目( ExpandedFlexible小部件)

階段1

Flutter 執行階段 1 時沒有考慮屏幕尺寸或任何其他限制。

Flutter 只是將所有非 flex-factor 項目大小加在一起。

屏幕或其他限制的總和太大? RenderFlex overflowed異常。

階段2

帶有flex構造函數參數的小部件是 flex-factor 項目。

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

在第 1 階段之后,任何 flex-factor 小部件的布局都考慮到了剩余空間


非靈活和彈性因子布局階段之間的主要區別

  • 非彈性布局 →不分空間
  • flex-factor 布局 → 使用剩余空間

ColumnRow ,將小部件包裝在ExpandedFlexible ,Flutter 將計算其布局的剩余空間。 這將防止問題中的RenderFlex overflowed異常,因為每個Image小部件都會根據空間限制調整自身大小

但在第一階段,沒有空間限制 所以Images沒有調整大小(和溢出)。

ColumnRow包含在ExpandedFlexible子小部件將以其固有大小進行布局,而不管屏幕/約束空間如何。

Space 400
  Column
    Image 150
    Image 150
    Image 150

總和非彈性圖像:450。可用空間:400 → Overflowed

解決方案:使用階段 2 → 使用計算空間

Image包裝在 flex 小部件Expanded計算可用高度,然后在Expanded之間共享(作為約束),並調整Image大小以適應Expanded約束:

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)它對我有用!

在你的Image.network方法中使用fit屬性來減小你的圖像的大小,因為它們更大並且從你的容器中溢出,或者你可以通過它們的heightwidth屬性來放大你的Containers

錯誤(由於鍵盤):

您也可以在使用啟動屏幕鍵盤的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(), ) ], )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM