ListView.builder in Flutter

Create efficient, dynamic lists with lazy rendering

Download Complete Examples

What is ListView.builder?

The ListView.builder is a ListView constructor that creates elements on demand. It's extremely efficient for long lists because it only renders the visible elements.

ListView Normal

Item 1
Item 2
Item 3
Item 4
Item 5
+ 95 items más...

Renders all items at the same time

ListView.builder

Item 1
Item 2
Item 3
Items 4-100 (virtualizados)

Renders only the visible items

Basic Syntax

Basic Constructor of ListView.builder

ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text(items[index]),
    );
  },
)

Main Features:

  • Lazy rendering: Only creates the visible elements
  • Efficient with long lists: Ideal for 100+ elements
  • Dynamic: Adapts to changes in the data
  • Customizable: Full control over each item

Main Parameters

itemCount

Total number of elements in the list

itemCount: myList.length

itemBuilder

Function that builds each element

itemBuilder: (context, index) {
return MyWidget(item[index]);
}

scrollDirection

Scroll direction (vertical/horizontal)

scrollDirection: Axis.vertical

When to use ListView.builder?

Long Lists

Lists with many elements (100+) where performance is crucial

// Lista de 1000 usuarios
ListView.builder(
itemCount: users.length,
itemBuilder: (ctx, i) => UserCard(users[i]),
)

Dynamic Data

Lists that change frequently or load from an API

// Lista de noticias en tiempo real
ListView.builder(
itemCount: news.length,
itemBuilder: (ctx, i) => NewsItem(news[i]),
)

Mobile Apps

Applications that display feeds, chats, or any extensive list

// Feed de redes sociales
ListView.builder(
itemCount: posts.length,
itemBuilder: (ctx, i) => PostCard(posts[i]),
)

Visual Examples

1. Basic List with ListTile

A
Ana García
ana@email.com
B
Carlos López
carlos@email.com
C
María Rodríguez
maria@email.com
ListView.builder(
  itemCount: users.length,
  itemBuilder: (context, index) {
    return ListTile(
      leading: CircleAvatar(
        child: Text(users[index].name[0]),
      ),
      title: Text(users[index].name),
      subtitle: Text(users[index].email),
      trailing: Icon(Icons.chevron_right),
      onTap: () => navigateToUser(users[index]),
    );
  },
)

2. Horizontal List

Category 1
Category 2
Category 3
Category 4
ListView.builder(
  scrollDirection: Axis.horizontal,
  itemCount: categories.length,
  itemBuilder: (context, index) {
    return Container(
      margin: EdgeInsets.all(8),
      padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      decoration: BoxDecoration(
        color: Colors.blue,
        borderRadius: BorderRadius.circular(20),
      ),
      child: Text(categories[index]),
    );
  },
)

3. List with Custom Items

Producto 1 \$29.99
Descripción del producto
★★★★☆
Producto 2 \$49.99
Descripción del producto
★★★★★
ListView.builder(
  itemCount: products.length,
  itemBuilder: (context, index) {
    return Card(
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(products[index].name),
                Text('\$${products[index].price}'),
              ],
            ),
            SizedBox(height: 8),
            Text(products[index].description),
            SizedBox(height: 8),
            Text('★' * products[index].rating),
          ],
        ),
      ),
    );
  },
)

Properties of the ListView.builder

Property Type Description Required
itemCount int Total number of elements in the list Optional*
itemBuilder IndexedWidgetBuilder Function that builds each element Yes
scrollDirection Axis Scroll direction (vertical/horizontal) No
padding EdgeInsets Space around the list No
physics ScrollPhysics Scroll behavior No
shrinkWrap bool Whether the list should adjust its size No

Note about itemCount:

If itemCount, isn't provided, the list will be infinite. This is useful for lists that load progressively or have an unknown number of elements.

Generator for ListView.builder

15 items
// El código se generará aquí

ListView.builder vs Alternatives

Widget Advantages Disadvantages When to use
ListView.builder Efficient, lazy loading, dynamic More complex for simple lists Long or dynamic lists
ListView Simple, direct Renders all items Short, static lists
Column Maximum control, flexible No automatic scroll, inefficient Small, fixed number of widgets
GridView.builder Efficient for grids Additional complexity Grid/column lists

Practical Exercises

Exercise 1: Task List

Create a task list where each item shows the title and completion status.

Solution:
ListView.builder(
  itemCount: tasks.length,
  itemBuilder: (context, index) {
    return CheckboxListTile(
      title: Text(tasks[index].title),
      value: tasks[index].completed,
      onChanged: (bool? value) {
        setState(() {
          tasks[index].completed = value!;
        });
      },
    );
  },
)

Exercise 2: Infinite List

Create a list that loads more elements when the user reaches the end.

Solution:
ListView.builder(
  itemCount: items.length + 1,
  itemBuilder: (context, index) {
    if (index == items.length) {
      // Mostrar loading al final      return Center(child: CircularProgressIndicator());
    }
    return ListTile(title: Text(items[index]));
  },
)

Exercise 3: List with Different Types

Create a list that shows different types of widgets based on the index.

Solution:
ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    if (index % 3 == 0) {
      return HeaderItem(items[index]);
    } else {
      return ContentItem(items[index]);
    }
  },
)

Tips and Best Practices

✅ What you SHOULD do

  • Use unique keys for items that can change
  • Implement pagination for very long lists
  • Use const constructors in itemBuilder when possible
  • Consider using ScrollController for advanced control

❌ What you should NOT do

  • Don't use setState inside itemBuilder
  • Avoid heavy calculations in itemBuilder
  • Don't forget itemCount in infinite lists
  • Don't use ListView.builder for very short lists

Pro Tip

For extremely long lists, consider using ListView.separated() which lets you define a custom separator between items, improving performance and appearance.