A scrollable list of widgets arranged linearly. It displays its children one after another in the scroll direction. In the cross axis, the children are required to fill the ListView.
If you have a short list of items that don't change, then you can use the default ListView constructor to make it. This is useful for making something like a settings menu page.
ListView( padding: const EdgeInsets.all(8), children: <Widget>[ Container( height: 50, color: Colors.amber[600], child: const Center(child: Text('Entry A')), ), Container( height: 50, color: Colors.amber[500], child: const Center(child: Text('Entry B')), ), Container( height: 50, color: Colors.amber[100], child: const Center(child: Text('Entry C')), ), ], )
The above code would produce the following output:
The builder()
constructor constructs a repeating list of items. The constructor takes two main parameters: An itemCount
for the number of items in the list and an itemBuilder
for constructed each list item.
final List<String> entries = <String>['A', 'B', 'C']; final List<int> colorCodes = <int>[600, 500, 100]; ListView.builder( padding: const EdgeInsets.all(8), itemCount: entries.length, itemBuilder: (BuildContext context, int index) { return Container( height: 50, color: Colors.amber[colorCodes[index]], child: Center(child: Text('Entry ${entries[index]}')), ); } );
The general format of the code is:
ListView.builder( itemCount: itemCount, itemBuilder: (context, position) { return listItem(); }, ),
The list items are constructed lazily, meaning only a specific number of list items are constructed and when a user scrolls ahead, the earlier ones are destroyed.
The itemCount
parameter specifies the total number of item in the list and itemBuilder
parameter should return the widget which will be displayed as the list item. The method that is assigned to itemBuilder
parameter gets two argument context
and position
. The position specifies the position or index of the each item in the list.
The argument itemCount
is optional. Without this parameter the list is infinite. In the following example, the scrolling never ends.
ListView.builder( itemBuilder: (context, position) { return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Text(position.toString(), style: TextStyle(fontSize: 22.0),), ), ); }, ),
The ListView.separated
constructor takes two IndexedWidgetBuilders
: itemBuilder
builds child items on demand, and separatorBuilder
similarly builds separator children which appear in between the child items. This constructor is appropriate for list views with a fixed number of children.
Note that the infinite count discussed in the earlier constructor cannot be used here and this constructor enforces an itemCount.
final List<String> entries = <String>['A', 'B', 'C']; final List<int> colorCodes = <int>[600, 500, 100]; ListView.separated( padding: const EdgeInsets.all(8), itemCount: entries.length, itemBuilder: (BuildContext context, int index) { return Container( height: 50, color: Colors.amber[colorCodes[index]], child: Center(child: Text('Entry ${entries[index]}')), ); }, separatorBuilder: (BuildContext context, int index) => const Divider(), );
This type of list lets you dynamically define separators, have different types of separators for different types of items, add or remove separators when needed, etc.
This implementation can also be used for inserting other types of elements (advertisements for example) easily and without any modification to the main list in the middle of the list items.
Note: The separator list length is 1 less than the item list as a separator does not exist after the last element.
To control the way scrolling takes place, we set the physics parameter in the ListView constructor. The different types of physics are:
NeverScrollableScrollPhysics
renders the list non-scrollable. Use this to disable scrolling of the ListView completely.
BouncingScrollPhysics
bounces back the list when the list ends. A similar effect is used on iOS.
This is the default scrolling physics used on Android. The list stops at the end and gives an effect indicating it.
This is slightly different than the other ones in this list in the sense that it only works with FixedExtendScrollControllers
and lists that use them. For an example we will take a ListWheelScrollView
wich makes a wheel-like list.
FixedExtentScrollPhysics
only scrolls to items instead of any offset in between.
FixedExtentScrollController fixedExtentScrollController = new FixedExtentScrollController(); ListWheelScrollView( controller: fixedExtentScrollController, physics: FixedExtentScrollPhysics(), children: monthsOfTheYear.map((month) { return Card( child: Row( children: <Widget>[ Expanded( child: Padding( padding: const EdgeInsets.all(8.0), child: Text( month, style: TextStyle(fontSize: 18.0), ), )), ], )); }).toList(), itemExtent: 60.0, ),