Flutter: "Vertical Viewport Was Given Unbounded Height" Problems
If you've ever done any Flutter UI development, you'll eventually encounter the Error: "Vertical Viewport Was Given Unbounded Height". And it won't be pretty. You'll see a long stack trace, and lots of text to read. I don't know about you but I usually say: "Why can't this just work?", "Why do I need all these error messages?".
Let's take a step back: This usually happens when you are using Columns and Rows which are Flutter's most basic widgets. You'll have a list of other widgets inside of them. Usually with no issues; unless one of those widgets is a ListView or another widget that can grow. Text widgets are fine because they are usually just one line.
You might start out your UI with something like this:
Scaffold(
body: Column(
children: [
Text('Hello world')
]
)
)
The Scaffold will pass down the height of the screen for the Column so you won't have any issues. If you get a bit more complex and start nesting like:
Scaffold(
body: Column(
children: [
Text('Hello world')
Row(
children: [
Text('Row Text')
]
)
Column(
children: [
ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return Text('Item $index');
}),
]
)
]
)
)
You are going to get a lot of errors. If you wrap the ListView in an Expanded widget, problem solved!
I started on a complex UI that looks like:
This was for a Taikawando studio. As you can see there are many different parts to this. Many Columns with Rows inside of them and then those rows might have columns. Everything went fine until I got to the ListView at the bottom. Here's a markup of the different widgets:
Once I got to the Upcoming Class section, everything exploded. I spent weeks trying to figure out how fix this, did lots of Google searches and found a few very important points:
Except for a Column inside of a Scaffold, Columns have infinite height.
Anything in a Column or Row that needs to take up as much room as possible needs an Expanded widget.
Expanded widgets can only be used inside of Columns and Rows.
What I was trying to do was fix the problem at the very bottom but the problem existed higher up as well. Since the ListView inside of the Column needed to be wraped in an Expanded, then so did the Columns above it.
Some of the ideas on the internet mentioned using shrinkwrap: true
for the ListView, but then others also mentioned that this slows things down. I found I didn't need it if the ListView is wrapped in an Expanded.
Also, one of the tips I can give, is to really break your UI into different widgets. Try putting them into their own widgets and test them separately to make sure they work. Then slowly put the whole thing together.
I hope this helps and saves you hours of time. I won't forget this lesson any time soon.