Beginning Flutter Debugging

Sep 29 2022 · Dart 2.18, Flutter 3.3, Visual Studio Code / Android Studio

Part 1: Beginning Flutter Debugging

09. Solve Layout Errors in ListViews

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 08. Debug Common Layout Issues Next episode: 10. Understand the Red Screen of Death

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Notes: 09. Solve Layout Errors in ListViews

Prerequesites: Basic knowledge of how ListViews work is needed. Please see our Flutter ListView Course. The student materials have been reviewed and are updated as of SEPTEMBER 2022.

Transcript: 09. Solve Layout Errors in ListViews

ListViews can also scroll horizontally. For this, we set the scrollDirection to horizontal like so:

...
scrollDirection: Axis.horizontal,
...

And we have an exception. Let’s open up the debug sidebar. If we hover on the message from the exception, it states that the “BoxConstraints forces an infinite width.” If we hit the continue button, we’ll see the next error states that the “Renderbox was not laid out.” Which means that that Flutter doesnt know how to lay out the ListView in this scenario.

Now, when items in a ListView are arranged vertically, it primarily works with the height of each child. Each child’s height can be determined by their contents since they are arranged from top to bottom. Or they can be explicitly defined.

While their widths would stretch to inifinity. In this case, they would be as big as their bounding box which is the ListView and the ListView takes up the width of the screen.

But thats different for horizontal ListViews. In here, we’re working with the width since we’re dealing in the horizontal space. The widths for each item would still be stretched to infinity if they are not constrained by a specific size. So if the first child’s width is infinity, then the second child can never be laid out hence resulting in this error.

If you used a widget like a Container and set a specific width, you wouldnt encounter this error. But thats not the case for the ListTile widget. It forces an infinite width because it is normally used in vertical ListViews and that is why we have this error.

To solve this, we could wrap each ListTile with a Container and specify a width but the ListView provides us with the itemExtent property that sets the extent for each child in the ListView.

Let’s add that now:

itemExtent: 200

And then we do a hot restart. We can see the items are laid out properly now.

The itemExtent helps with performance as Flutter knows how much horizontal space to allocate to each child beforehand. Note: for horizontal ListViews, the itemExtent acts as the width. While for vertical ListViews, it acts as the height.

body: ListView(
  children: List.generate(20, (index) {
    return const CardItem();
  }),
),

Finally, nested scroll views are common in many modern UIs. You could have a horizontal ListView inside a vetical ListView. This should be easy, right? Well, let’s add a horizontal ListView inside the ListView to display an Ad. Update your code to the following:

body: ListView(
  children: List.generate(10, (index) {
    // New Code
    if (index == 2) {
      return ListView(
          scrollDirection: Axis.horizontal,
          children: List.generate(10, (index) => const AdvertBox()),
      );
    }
    // End New Code
    return const CardItem();
  }),
),

In here, we added a horizontal ListView that contains advertboxes at the second index of the vertical ListView. And exception occured and it states that: “Horizontal viewport was given unbounded height.” and this quite similar to the error we had when dealing with with a ListView inside a Column.

Now, setting the shrinkWrap property to true wont solve this because that property affects the extent of the scroll direction. In this case it would affect the width and this is not what we want.

We need to bound the height to a constrained vertical space so the items of the outer vertical ListView can be laid out properly. So to solve this, we’ll wrap the inner ListView with a SizedBox and specify a height like so:

return SizedBox(
  height: 100,
  child: ListView(
    ...

Save your work and do a hot restart. This solves the error because Flutter now knows the height of the inner ListView while laying it out.

If you’re new to ListViews you may want to check out the first part of our course: “Flutter ListView.”