ListView is a scrollable widget that arranges its children linearly in one direction. Unlike Column or Row, ListView handles:
This makes it suitable for feeds, settings screens, long forms, and any UI where content may exceed the available screen space.
Understanding the difference between Column and ListView is essential. This is one of the most common beginner mistakes in Flutter app development.
If content can grow or should scroll, ListView is almost always the correct choice.
ListView.builder is the most commonly used and recommended constructor.
It creates list items lazily, meaning widgets are built only when they become visible on screen. This is critical for performance when working with data from APIs, databases, or any list larger than a few dozen items.
A simple rule of thumb:
ListViewListView.builderUsing ListView with a children list generated by a for-loop may look convenient, but it scales poorly and should be avoided for real data.
ListView.separated is a variant of ListView.builder that inserts a separator widget between items.
It is commonly used for:
Both items and separators are built lazily, making it safe for large lists.
ListView.separated(
itemCount: 20,
separatorBuilder: (_, _) => const Divider(),
itemBuilder: (context, index) => ListTile(
title: Text('Item $index'),
),
);This pattern is ideal for settings screens and simple scrollable lists.
One of the most common Flutter errors appears when placing a ListView inside a Column or Row.
The typical error message is: Vertical viewport was given unbounded height
The reason is simple:
Column wants to know how tall its children are.ListView wants infinite height so it can scrollThis creates a layout conflict.
The solution is to wrap ListView with Expanded (or Flexible), which tells Flutter to give the list the remaining available space.
Without Expanded, ListView inside Column or Row will almost always break.
Typical issues include:
Column instead of ListView for scrollable contentListView inside Column without wrapping it in ExpandedListView(children: […]) for large or dynamic datasets8 min. • Nov 8, 2022
Almost every production-grade app depends on tens of packages. Using them allows for quick implementation of standard functionalities. Take a closer look at 6 useful but not-so-popular Dart and Flutter packages made and tested by LeanCode's devs.
10 min • Oct 27, 2025
In this article, we’re sharing LeanCode’s 12 practical Flutter and Dart patterns that help you write less boilerplate, make your code cleaner, and catch mistakes earlier. Apply these patterns and you'll find yourself coding faster, communicating more clearly with your teammates, and spending less time debugging issues that the compiler could have caught.