Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter RenderFlex overflowed by 15 pixels on the right inside Column Widget

Tags:

flutter

I created a custom ListTile which should have two score centered in the middle and information on the left and right of this (screenshot).

The information on the left can have arbitrary length and should use TextOverflow.ellipsis when it's too long. I cannot get this to work since the Text does not seem to know the width it is supposed to have and overflows. I have tried wrapping the Text widgets into SizedBox, Expanded, etc. This has not worked.

    flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
    flutter: The following message was thrown during layout:
    flutter: A RenderFlex overflowed by 15 pixels on the right.
    flutter:
    flutter: The overflowing RenderFlex has an orientation of Axis.horizontal.
    flutter: The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
    flutter: black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
    flutter: Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the
    flutter: RenderFlex to fit within the available space instead of being sized to their natural size.
    flutter: This is considered an error condition because it indicates that there is content that cannot be
    flutter: seen. If the content is legitimately bigger than the available space, consider clipping it with a
    flutter: ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex,
    flutter: like a ListView.
    flutter: The specific RenderFlex in question is:
    flutter:   RenderFlex#c64e4 relayoutBoundary=up11 OVERFLOWING
    flutter:   creator: Row ← Expanded ← Row ← Column ← ConstrainedBox ← Container ← Listener ← _GestureSemantics
    flutter:   ← RawGestureDetector ← GestureDetector ← InkWell ← ScopedModelDescendant<BaseballModel> ← ⋯
    flutter:   parentData: offset=Offset(0.0, 0.0); flex=1; fit=FlexFit.tight (can use size)
    flutter:   constraints: BoxConstraints(w=143.0, 0.0<=h<=Infinity)
    flutter:   size: Size(143.0, 70.0)
    flutter:   direction: horizontal
    flutter:   mainAxisAlignment: start
    flutter:   mainAxisSize: max
    flutter:   crossAxisAlignment: center
    flutter:   textDirection: ltr
    flutter:   verticalDirection: down
    flutter: ◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤

My Code is the following:

@immutable
class GameTile extends StatelessWidget {
  final Game game;
  Color highligtColor = Colors.red;

  GameTile({this.game});

  @override
  Widget build(BuildContext context) {
    return InkWell(
      child: Container(
        height: 70.0,
        child: Column(
          children: <Widget>[
            Row(
              children: <Widget>[
                Expanded(
                  child: Row(
                    children: <Widget>[
                      Container(
                        width: 8.0,
                        height: 70.0,
                        color: highligtColor,
                      ),
                      Padding(
                        padding: EdgeInsets.only(left: 15.0),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Text(
                              game.awayTeam.name,
                              overflow: TextOverflow.ellipsis,
                            ),
                            Text(
                              game.homeTeam.name,
                              overflow: TextOverflow.ellipsis,
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 8.0, right: 8.0),
                  child: Column(
                    children: [
                      Text(
                        game.awayRuns,
                        style: TextStyle(fontWeight: FontWeight.w900),
                      ),
                      Text(
                        game.homeRuns,
                        style: TextStyle(fontWeight: FontWeight.w900),
                      ),
                    ],
                  ),
                ),
                Expanded(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      Column(
                          crossAxisAlignment: CrossAxisAlignment.end,
                          children: <Widget>[
                            Text(game.getFormattedDate()),
                            Text(game.getFormattedTime()),
                          ]),
                      Padding(
                        padding: EdgeInsets.only(left: 8.0, right: 10.0),
                        child: Container(),
                      )
                    ],
                  ),
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}
like image 946
Daniel Palenicek Avatar asked Oct 16 '18 10:10

Daniel Palenicek


People also ask

How do you fix a right overflow error in flutter?

AnswerSet the dropdown's inner contents to horizontally fill its parent. By default this button's inner width is the minimum size of its contents. If [isExpanded] is true, the inner width is expanded to fill its surrounding container.

How do I fix RenderFlex overflowed in flutter?

To fix A RenderFlex overflowed by pixels you just have to Wrap Image in flex widget Expanded , height available is calculated then shared among Expanded (as constraints) and Image is resized to fit inside Expanded constraints.

How do you handle overflow in flutters?

The Text may overflow from the widgets like containers, cards, etc. The Text Widget has a property overflow to handle the overflow text in android, IOS, WEB, desktop applications. Overflow property has multiple parameters like clip, ellipsis, fade, visible, etc.


2 Answers

Just wrap the overflowed widget with Flexible

new Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            new Checkbox(
              onChanged: (bool){},
            ),
            Flexible(
              child: new Text(
                "This text can be so loooooooooooooong",
              ),
            ),

          ],
        ),
like image 158
Pablo Cegarra Avatar answered Sep 21 '22 08:09

Pablo Cegarra


About the exception

I ran your code on my phone and an exception occurred only after meddling with the teams names and the width of the widget.

I think this problem arises because your code doesn't adapt to different display sizes well enough, especially if the team names have a different length:

both your widget and the modified version

Concrete solution for a more flexible and dynamic widget

I created a modified widget that adapts well to constraint changes and uses the available space in a more clever way. I did this by flattening your nested Rows and Columns as far as possible, resulting in a more shallow, more flexible widget tree:

return InkWell(
  child: Container(
    height: 70.0,
    child: Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        Container(width: 8.0, height: 70.0, color: highlightColor),
        SizedBox(width: 15.0),
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(game.awayTeam.name, overflow: TextOverflow.ellipsis),
            Text(game.homeTeam.name, overflow: TextOverflow.ellipsis),
          ],
        ),
        Spacer(),
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(game.awayRuns, style: TextStyle(fontWeight: FontWeight.w900)),
            Text(game.homeRuns, style: TextStyle(fontWeight: FontWeight.w900)),
          ],
        ),
        Spacer(),
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: <Widget>[
            Text(game.getFormattedDate()),
            Text(game.getFormattedTime()),
          ]
        ),
        SizedBox(width: 18.0),
      ],
    ),
  ),
);

General tip when dealing with difficult constraints

Most of the time, it's better to use just a few widgets in a shallow tree. Nesting all kinds of "organizational" widgets, especially Columns, Rows and Expandeds often creates situations where an Expanded always requests the same size (or ratio of the parent size) without even considering the dimensions of its content.

That can lead to content overflowing, while there is unused negative space at other parts of the widget.

like image 27
Marcel Avatar answered Sep 21 '22 08:09

Marcel