Displaying a List of Widgets in Flutter
Flutter, provides powerful widgets for creating dynamic user interfaces. In this post, we will explore how to display a list of widgets using ListView.builder
and GridView.builder
widgets in Flutter. These approaches are efficient because they dynamically build only the widgets that are visible on the screen, making them ideal for displaying large lists of data.
1. Using the ListView.builder widget
When displaying large lists of data in a Flutter application, optimizing performance is crucial. The ListView.builder
widget provides an efficient solution by dynamically building only the visible widgets on the screen. This approach improves rendering speed and reduces memory usage, making it the ideal choice for handling extensive datasets in Flutter applications.
For demonstration purposes, I have created a simple application that uses the ListView.builder
widget to display a list of ListTile
widgets.
The application uses a list of generated strings called items
as the data source. You can easily replace this list with your own data. See the code snippet below:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({super.key});
final List items = List.generate(100, (index) => 'item $index');
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'List of Widgets Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('List of Widgets Example'),
),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
final item = items[index];
return ListTile(
title: Text(item),
);
},
),
),
);
}
}
Inside the Scaffold
, the body
property is set to a ListView.builder
widget. This widget dynamically builds the list of widgets based on the items
list.
The ListView.builder
widget takes two parameters: itemCount
and itemBuilder
. The itemCount
is set to the length of the items
list. The itemBuilder
takes a callback function that builds a widget for each item in the list.
Inside the itemBuilder
callback, the corresponding item from the items
list is retrieved using the index
parameter. For each item, a ListTile
widget is created with a Text
widget as the title, displaying the item's data.
In the screenshot below you can see the result of our implementation.

It is a simple list that displays the data that we have given to the callback function inside the itemBuilder
property. You can see that all our items are displayed because we set the itemCount
property to the length of our items
list.
If you are looking to display items in multiple columns, Flutter has you covered with the GridView.builder
widget.
We created a simple list using ListView.builder
. The items displayed on the screen were determined by the data provided to the callback function inside the itemBuilder
property. By setting the itemCount
property to the length of our items
list, we ensured that all of our items were displayed.
We can take it a step further and display our items in multiple columns. Flutter has the perfect solution for that: the GridView.builder
widget. With the GridView.builder
widget, you can easily arrange your items in a grid layout, providing a more organized list.
2. Using the GridView.builder widget
Using the GridView.builder
widget is very similar to using the ListView.builder
widget. All we have to do is replace the ListView.builder
widget from the previous code snippet with the following code:
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
final item = items[index];
return Card(
child: Center(
child: Text(item),
),
);
},
)
In our implementation of the GridView.builder
widget, we focused on three key parameters: gridDelegate
, itemCount
, and itemBuilder
. The gridDelegate
is responsible for determining the layout of the grid. In this example, we used theSliverGridDelegateWithFixedCrossAxisCount
class to specify the number of columns using the crossAxisCount
property.
The itemCount
is set to the length of the items
list, ensuring that the grid contains the exact number of items.
For each item in the list, the itemBuilder
callback function is invoked. Within this function, we retrieve the corresponding item from the items
list using the index
parameter.
To represent each item in the grid, instead of using the ListTile
widget as before we use the Card
widget with a Text
widget at its center, displaying the data of the item. This will result in the following:

As you can see the displayed data is now displayed in two columns. You can play around by changing crossAxisCount
inside the SliverGridDelegateWithFixedCrossAxisCount
class. We can also change the size of the displayed items by adding the childAspectRatio
property, see the code snippet below:
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 2,
),
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
final item = items[index];
return Card(
child: Center(
child: Text(item),
),
);
},
)
We have set the crossAxisCount
to 3
, this will make our grid three columns wide. Also, we have added the childAspectRatio
of 2
. This will decrease the size of our GridView
items because the default of this property is 1
.

As you can see the items are much smaller than before.
3. Conclusion
In this blog post, we explored the power of ListView.builder
and GridView.builder
in Flutter for efficiently displaying widgets in lists and grids. These widgets dynamically render only the visible items, resulting in improved performance and reduced memory usage.
With ListView.builder
, we learned how to create scrolling lists efficiently, optimizing performance by recycling items as the user scrolls. By leveraging the itemBuilder
callback function, we can handle large datasets without compromising the user experience.
We also explored GridView.builder
, which simplifies the creation of grids. By specifying the grid layout with gridDelegate
and providing an itemBuilder
function, we can efficiently render grids that adapt to different screen sizes and orientations.
Consider using ListView.builder
or GridView.builder
in your Flutter applications to achieve optimal performance and an efficient user interface when displaying lists or grids of data.