There are a number of ways to do the same thing. Let me compare them here.
For a short static list
Use ListTile.divideTiles
ListView(
children: ListTile.divideTiles( // <-- ListTile.divideTiles
context: context,
tiles: [
ListTile(
title: Text('Horse'),
),
ListTile(
title: Text('Cow'),
),
ListTile(
title: Text('Camel'),
),
ListTile(
title: Text('Sheep'),
),
ListTile(
title: Text('Goat'),
),
]
).toList(),
)
For a long dynamic list
Use ListView.separated
.
ListView.separated(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(
title: Text('$index sheep'),
);
},
separatorBuilder: (context, index) {
return Divider();
},
)
This returns two widgets for every item, except for the last item. The separatorBuilder
is used to add the divider.
For adding a divider after the last item
Create a custom item widget that uses a Divider or BoxDecoration.
Using Divider
final items = ['Horse', 'Cow', 'Camel', 'Sheep', 'Goat'];
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Column(
children: <Widget>[
ListTile(
title: Text(items[index]),
),
Divider(), // <-- Divider
],
);
},
);
}
Using BoxDecoration
final items = ['Horse', 'Cow', 'Camel', 'Sheep', 'Goat'];
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration( // <-- BoxDecoration
border: Border(bottom: BorderSide()),
),
child: ListTile(
title: Text(items[index]),
),
);
},
);
}
Both Divider and BoxDecoration are customizable as far as the line height and color go. Divider also has an indent option, but you could get a BoxDecoration to do the same thing with some padding.
For more style
Use a Card
final items = ['Horse', 'Cow', 'Camel', 'Sheep', 'Goat'];
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Card( // <-- Card
child: ListTile(
title: Text(items[index]),
),
);
},
);
}