Le Widget ListTile dans Flutter
Le Widget ListTile dans Flutter
-
Objectifs
-
Présentation
- Le widget ListTile est un composant très utile dans Flutter pour créer des listes d’éléments qui peuvent être sélectionnés, ou qui montrent simplement des informations. Il est souvent utilisé à l’intérieur de listes déroulantes comme ListView, GridView, ListWheelScrollView, etc. pour afficher des éléments dans une liste.
-
Composant du ListTile : Structuration d’Éléments dans une Liste
- Un ListTile typique est divisé en trois sections ; Début, Centre et Fin.
- Début (Leading) : Cette section contient généralement le widget principal, tel qu’une icône ou une image. C’est affiché à gauche du contenu principal du ListTile.
- Centre (Title et Subtitle) : Cette section comprend le titre principal et éventuellement un sous-titre. Le titre est généralement le texte principal que vous souhaitez afficher, tandis que le sous-titre peut fournir des informations supplémentaires.
- Fin (Trailing) : Cette section est située à droite du contenu principal du ListTile. Elle contient généralement un widget tel qu’une icône, un bouton ou tout autre élément d’action. Cela peut être utilisé pour indiquer une action supplémentaire associée à l’élément du ListTile.
- Voici un exemple illustrant ces trois sections dans un ListTile :
- Dans cet exemple :
leading
contient une icône qui est située à gauche du texte principal.title
contient le texte principal, « John Doe ».subtitle
contient le sous-titre, « john.doe@example.com ».trailing
contient une icône qui est située à droite du texte principal et du sous-titre.- Ces sections offrent une grande flexibilité pour la conception et l’affichage des éléments dans une liste dans Flutter.
-
Variantes du ListTile
- Le
widget ListTile
est incroyablement polyvalent, et ses variantes offrent encore plus de possibilités de personnalisation. Voici quelques-unes des variantes les plus couramment utilisées : ListTile simple
: Cette variante est la version de base du ListTile. Elle comprend une icône ou une image à gauche, un titre au centre, et éventuellement une icône ou un bouton facultatif à droite.ListTile avec interrupteur (Switch)
: Cette variante ajoute un interrupteur à la fin du ListTile, ce qui permet à l’utilisateur de basculer facilement entre deux valeurs booléennes.ListTile avec sous-titre
: En plus des composants du ListTile simple, cette variante inclut un sous-titre en dessous du titre. Cela peut être utile pour fournir plus de contexte ou d’informations sur l’élément affiché.ListTile avec icône uniquement
: Cette variante ne comporte qu’une icône, sans texte. Elle est pratique pour afficher des symboles ou des logos plutôt que du texte.ListTile avec case à cocher
: Cette variante comprend une case à cocher à gauche, permettant aux utilisateurs de sélectionner plusieurs éléments ou de les marquer comme terminés. Le titre et un sous-titre facultatif peuvent être inclus à droite.ListTile avec bouton radio
: Similaire à la variante avec case à cocher, mais avec des boutons radio à la place. Seul un élément peut être sélectionné à la fois, ce qui en fait un choix idéal pour les options ou les choix exclusifs.ListTile personnalisé
: Cette variante offre une flexibilité maximale en permettant aux utilisateurs d’ajouter leurs propres widgets ou éléments au ListTile. Cela peut inclure des images, des boutons, ou du texte supplémentaire, offrant ainsi une personnalisation totale de l’apparence et du comportement du ListTile.-
Application
-
Partie:01
- Reprenez le code donné pour le widget « ListTile simple ».
- Ajoutez une couleur d’arrière-plan au « AppBar » et le texte « Utiliser ListTile ».
- Supprimez la barre oblique située à droite de l’écran.
- Centrez les deux ListTile au centre haut de l’écran et ajoutez un espace autour des ListTiles.
- Colorez les ListTiles et ajoutez les numéros de téléphone sous chaque nom.
- Coloriez chaque ListTile avec une couleur différente.
-
Partie:02
- Comment pourriez-vous modifier ce code pour remplacer les ListTile par des ListTile avec interrupteur (Switch) tout en conservant le même agencement et la même disposition centrée ?
- En utilisant l’exemple donné, expliquez comment vous pourriez adapter la gestion des événements (onTap) pour chaque ListTile si vous deviez utiliser un interrupteur (Switch) à la place.
-
Partie:03
-
Partie:04
- En utilisant l’exemple donné de ListTile avec interrupteur (Switch), pouvez-vous ajouter deux autres ListTile à la liste existante ? Cette fois-ci, les nouveaux ListTile devraient contenir une case à cocher à gauche, permettant aux utilisateurs de sélectionner plusieurs éléments ou de les marquer comme terminés.
ListTile(
leading: Icon(Icons.person), // Début
title: Text('John Doe'), // Centre - Titre
subtitle: Text('john.doe@example.com'), // Centre - Sous-titre
trailing: Icon(Icons.arrow_forward), // Fin
onTap: () {
// Action à effectuer lorsque l'utilisateur appuie sur cet élément
print('ListTile tapped');
},
)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('ListTile Simple Example'),
),
body: ListView(
children: [
ListTile(
leading: Icon(Icons.person),
title: Text('John Doe'),
trailing: Icon(Icons.arrow_forward),
onTap: () {
// Action à effectuer lorsque l'utilisateur appuie sur cet élément
print('ListTile tapped');
},
),
ListTile(
leading: Icon(Icons.person),
title: Text('Jane Smith'),
trailing: Icon(Icons.arrow_forward),
onTap: () {
// Action à effectuer lorsque l'utilisateur appuie sur cet élément
print('ListTile tapped');
},
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State {
bool _switchValue = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('ListTile avec Switch'),
),
body: ListView(
children: [
ListTile(
title: Text('Notification Push'),
trailing: Switch(
value: _switchValue,
onChanged: (newValue) {
setState(() {
_switchValue = newValue;
});
},
),
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('ListTile avec Sous-titre'),
),
body: ListView(
children: [
ListTile(
leading: Icon(Icons.book),
title: Text('Article Flutter'),
subtitle: Text('Introduction à Flutter et Dart'),
trailing: Icon(Icons.arrow_forward),
onTap: () {
// Action à effectuer lorsque l'utilisateur appuie sur cet élément
print('ListTile tapped');
},
),
ListTile(
leading: Icon(Icons.book),
title: Text('Article Dart'),
subtitle: Text('Introduction au langage de programmation Dart'),
trailing: Icon(Icons.arrow_forward),
onTap: () {
// Action à effectuer lorsque l'utilisateur appuie sur cet élément
print('ListTile tapped');
},
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('ListTile avec Icône uniquement'),
),
body: ListView(
children: [
ListTile(
leading: Icon(Icons.camera),
onTap: () {
// Action à effectuer lorsque l'utilisateur appuie sur cet élément
print('ListTile tapped');
},
),
ListTile(
leading: Icon(Icons.album),
onTap: () {
// Action à effectuer lorsque l'utilisateur appuie sur cet élément
print('ListTile tapped');
},
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State {
bool _isChecked1 = false;
bool _isChecked2 = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('ListTile avec Case à cocher'),
),
body: ListView(
children: [
ListTile(
leading: Checkbox(
value: _isChecked1,
onChanged: (bool? value) {
setState(() {
_isChecked1 = value!;
});
},
),
title: Text('Tâche 1'),
subtitle: Text('Description de la tâche 1'),
onTap: () {
setState(() {
_isChecked1 = !_isChecked1;
});
},
),
ListTile(
leading: Checkbox(
value: _isChecked2,
onChanged: (bool? value) {
setState(() {
_isChecked2 = value!;
});
},
),
title: Text('Tâche 2'),
subtitle: Text('Description de la tâche 2'),
onTap: () {
setState(() {
_isChecked2 = !_isChecked2;
});
},
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State {
int _selectedValue = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('ListTile avec Bouton Radio'),
),
body: ListView(
children: [
ListTile(
leading: Radio(
value: 1,
groupValue: _selectedValue,
onChanged: (value) {
setState(() {
_selectedValue = value as int;
});
},
),
title: Text('Option 1'),
onTap: () {
setState(() {
_selectedValue = 1;
});
},
),
ListTile(
leading: Radio(
value: 2,
groupValue: _selectedValue,
onChanged: (value) {
setState(() {
_selectedValue = value as int;
});
},
),
title: Text('Option 2'),
onTap: () {
setState(() {
_selectedValue = 2;
});
},
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('ListTile Personnalisé'),
),
body: ListView(
children: [
CustomListTile(
title: 'Mon Titre',
subtitle: 'Mon sous-titre',
leading: Icon(Icons.person),
trailing: Icon(Icons.arrow_forward),
onTap: () {
// Action à effectuer lorsque l'utilisateur appuie sur cet élément
print('ListTile personnalisé tapé');
},
),
],
),
),
);
}
}
class CustomListTile extends StatelessWidget {
final String title;
final String subtitle;
final Widget leading;
final Widget trailing;
final VoidCallback onTap;
const CustomListTile({
required this.title,
required this.subtitle,
required this.leading,
required this.trailing,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return ListTile(
leading: leading,
title: Text(title),
subtitle: Text(subtitle),
trailing: trailing,
onTap: onTap,
);
}
}
-
« Imaginez que vous ayez ajouté des interrupteurs (Switch) à chaque ListTile de votre application. Cependant, lorsque vous essayez de changer l’état des interrupteurs, ceux-ci ne restent pas dans leur place et leur valeur ne se met pas à jour. Pouvez-vous identifier la raison pour laquelle cela se produit? Si non, proposez une solution pour corriger ce problème. »