Skip to content

Listes Flutter

Le widget ListView permet d’afficher les listes verticales ou horizontales.

ListView(
children: items
.map((item) => ListTile(title: Text(item)),)
.toList(),
)

ListView propose plusieurs constructeurs. ListView.builder a l’avantage de recycler les élements et d’optimiser leur instanciation, améliorant ainsi les performances proportionnellement aux nombres d’élements dans la liste.

ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) => UserTile(users[index]),
)
ListView.separated(
itemCount: users.length,
itemBuilder: (context, index) => UserTile(users[index]),
separatorBuilder: (context, index) => const Divider(),
)

Pour les item de la liste, il existe un widget ListTile permettant de définir :

  • le contenu de l’item
    • un title
    • un subtitle
    • un trailing : un emplacement en fin de ligne, en général pour un icône
    • un leading : un emplacement en début de ligne, en général pour un icône
  • l’état de l’item :
    • selected
    • enabled
  • des écouteurs d’évenement :
    • onTap
    • onLongPress
  • les couleurs :
    • textColor
    • tileColor
    • iconColor
    • selectedColor
    • selectedTileColor
    • hoverColor
    • focusColor
  • des options de layout :
    • dense
    • contentPadding
    • horizontalTitleGap
    • minLeadingWidth
    • minVerticalPadding
ListTile(
leading: const Icon(Icons.account_circle),
trailing: selection.contains(item) ? const Icon(Icons.check) : null,
title: Text(item),
subtitle: Text('Sous-titre $item'),
onTap: () {
selection.contains(item) ? selection.remove(item) : selection.add(item);
setState(() {});
},
)
class ListScreen extends StatefulWidget {
const ListScreen({Key? key}) : super(key: key);
@override
State<ListScreen> createState() => _ListScreenState();
}
class _ListScreenState extends State<ListScreen> {
final List<String> items = const ['Item A', 'Item B', 'Item C'];
final List<String> selection = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView(
children: items.map((item) {
final selected = selection.contains(item);
return ItemTile(item, selected: selected, onTap: () {
selected ? selection.remove(item) : selection.add(item);
setState(() {});
});
}).toList(),
),
);
}
}
class ItemTile extends StatelessWidget {
final String item;
final bool selected;
final VoidCallback onTap;
const ItemTile(
this.item, {
required this.selected,
required this.onTap,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
leading: const Icon(Icons.account_circle),
trailing: selected ? const Icon(Icons.check) : null,
title: Text(item),
subtitle: Text('Sous-titre $item'),
onTap: onTap,
);
}
}
class MainScreen extends StatelessWidget {
const MainScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
childAspectRatio: 16 / 9,
children: List.generate(
37,
(index) => GridTile(
key: Key('item$index'),
header: const Text('Header'),
footer: const Text('Footer'),
child: Center(
child: Text(
'ITEM $index',
overflow: TextOverflow.ellipsis,
maxLines: 10,
),
),
),
),
),
);
}
}