What's the difference between `ListView(children: [...])` and `ListView.builder`, and why does it matter?
Show answer — try answering out loud first
ListView with children builds all the items at once, even those not visible on screen. ListView.builder builds items on demand (only the visible ones and a few nearby), reusing them as you scroll. For long lists or lists of unknown size, always use ListView.builder; it's far more efficient in memory and performance.
ListView(children: [...]): you pass it a fixed list of already-created widgets. Flutter instantiates all of them. It's fine for a few things (5-10 fixed items).ListView.builder: you give it anitemCountand anitemBuilderthat creates each item when needed. Flutter only builds the ones that are (or are about to be) on screen, and recycles the ones that leave. This is called lazy loading.
If you have 10,000 items and use the first form, you create 10,000 widgets all at once: the app consumes a lot of memory and can freeze. With builder, only the visible ones exist.
import 'package:flutter/material.dart';
// Bad for long lists: creates ALL items at once
class FixedList extends StatelessWidget {
const FixedList({super.key});
@override
Widget build(BuildContext context) {
return ListView(
children: const [
ListTile(title: Text("Item 1")),
ListTile(title: Text("Item 2")),
ListTile(title: Text("Item 3")),
],
);
}
}
// Good for long lists: creates items on demand
class LargeList extends StatelessWidget {
final List<String> items;
const LargeList({super.key, required this.items});
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
// Only called for the visible items (and a few nearby)
return ListTile(title: Text(items[index]));
},
);
}
}
Using ListView(children: ...) with a long list generated by a map or a for. Even though it works, it builds everything at once and wastes memory. Another related mistake: putting a ListView inside a Column without constraining its height, which causes layout errors ("unbounded height"); in that case it's better to wrap it in Expanded or use shrinkWrap.
"
ListViewwithchildrencreates all the items at once, and it's only good for short, fixed lists.ListView.buildercreates them on demand withitemCountanditemBuilder: Flutter builds only the visible ones and recycles those that leave the screen, which is lazy loading. For long lists or lists of unknown size I always usebuilder, because with the other form a list of thousands of items would consume a huge amount of memory and freeze the app."
You need to show a list of 5,000 products coming from an API. Which widget do you use and why?
See answer
ListView.builder. With 5,000 items, ListView(children: ...) would create all 5,000 widgets at once, wasting a lot of memory and risking jank. ListView.builder only builds the ones on screen (and a few around them), recycling them as you scroll, so consumption stays low no matter how many products there are.