À quoi sert le Widget Textfield dans Flutter ?
Le widget TextField
est un composant essentiel dans Flutter permettant à vos utilisateurs de saisir des informations dans une barre de texte. Il peut être utilisé aussi bien pour la saisie de texte dans un formulaire que la création de champs de recherche interactifs. Vous pouvez par exemple l’utiliser pour :
-
Créer un formulaire de connexion : Le champ
TextField
permet à l’utilisateur de saisir son nom d’utilisateur ou son mot de passe. - Ajouter une barre de recherche dans une application : Il peut être utilisé pour filtrer des données en fonction de la saisie de l’utilisateur (comme une barre de recherche dans une application de shopping).
-
Prendre des notes : Dans une application de prise de notes, un
TextField
permet d’enregistrer des textes rapidement et de manière intuitive.
Comment intégrer un TextField dans Flutter
Une des propriétés les plus importantes lors de la mise en place d’un Textfield est le TextEditingController. En effet, ce widget est utilisé pour contrôler et accéder au texte que l’utilisateur saisit dans le TextField
. Il permet de :
- Récupérer le texte saisi.
- Mettre à jour le texte dans le champ de manière programmatique.
- Écouter les modifications du texte si nécessaire.
Il est donc important que chaque TextField
que vous allez créer ait son propre TextEditingController
. En effet, chaque champ de texte doit pouvoir gérer son propre état indépendamment, et partager un seul contrôleur entre plusieurs TextField
peut entraîner des comportements imprévisibles.
Ceci dit, voici un exemple simple de mise en place d’un widget TextField dans une application Flutter :
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('Exemple TextField Simple'),
),
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// Créer un TextEditingController pour le TextField
TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// TextField avec un controller
TextField(
controller: _controller, // Associe le controller à ce TextField
decoration: InputDecoration(
labelText: 'Entrez votre texte',
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Affiche le texte saisi dans la console
print('Texte saisi: ${_controller.text}');
},
child: Text('Afficher le text dans la console'),
),
],
),
);
}
}
Pourquoi un TextField doit toujours être placé dans un StatefulWidget ?
Le widget TextField
doit toujours être intégré dans un StatefulWidget
, car il est interactif et l’état du texte qu’il contient peut changer au fil du temps, en fonction de ce que l’utilisateur saisit.
Un StatelessWidget
ne permet pas de gérer ces modifications, car il est conçu pour afficher des éléments statiques, immuables. À l’inverse, un StatefulWidget
est capable de maintenir et d’actualiser son état interne (comme le texte saisi), ce qui est essentiel lorsque vous voulez que le texte saisi soit stocké, modifié ou récupéré via un TextEditingController
.
Ainsi, pour que le texte du champ soit correctement mis à jour et que vous puissiez y accéder, il est impératif d’utiliser un StatefulWidget
.
Envoyer une entrée dans Firebase
La plupart du temps, vous souhaiterez stocker quelque part le texte entré par l’utilisateur, par exemple dans votre base de données Firebase. Voici un court exemple de comment envoyer un message et son heure d’ajout, vers le back-end :
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart'; // Import de Firestore
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('TextField vers Firebase'),
),
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// Création du TextEditingController pour le TextField
TextEditingController _controller = TextEditingController();
// Fonction pour envoyer les données vers Firestore
Future<void> _sendDataToFirebase(String text) async {
// Ajoute le texte dans la collection "messages" de Firestore
await FirebaseFirestore.instance.collection('messages').add({
'texte': text, // Stocker le texte saisi
'timestamp': FieldValue.serverTimestamp(), // Ajouter un horodatage
});
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// TextField avec un controller pour capturer le texte
TextField(
controller: _controller,
decoration: InputDecoration(
labelText: 'Entrez un message',
border: OutlineInputBorder(),
),
),
SizedBox(height: 20),
// Bouton pour envoyer les données vers Firestore
ElevatedButton(
onPressed: () {
_sendDataToFirebase(_controller.text); // Envoyer le texte à Firebase
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Données envoyées à Firebase')),
);
_controller.clear(); // Effacer le champ après envoi
},
child: Text('Envoyer à Firebase'),
),
],
),
);
}
}
Vider le contenu du Textfield après l’envoi des données
Une fois les données envoyées vers Firebase, vous souhaiterez probablement que le Textfield se vide de son contenu, plutôt que l’utilisateur ait à l’effacer manuellement pour pouvoir écrire un nouveau message.
Pour cela, vous pouvez utiliser la méthode _controller.clear()
qui permet de vider le contenu du TextField
après qu’une action a été effectuée. Elle effacera simplement le texte actuellement saisi dans le champ de texte en le remplaçant par une chaîne vide (""
).
Personnaliser un TextField
Le widget TextField
peut être personnalisé de différentes façons pour améliorer l’expérience utilisateur et l’adapter à vos besoins spécifiques. Voici quelques-unes des propriétés les plus courantes et utiles pour personnaliser son comportement ou son design.
decoration
La propriété decoration
permet de personnaliser l’apparence du TextField
. Elle utilise généralement le widget InputDecoration
, qui offre de nombreuses options comme le label, la bordure et les icônes. Par exemple :
TextField(
decoration: InputDecoration(
labelText: 'Nom', //Texte qui apparait au dessus du champ quand l'utilisateur se met à taper
hintText: 'Entrez votre nom', //Text d'indication à l'intérieur du champ
border: OutlineInputBorder(), // Ajoute une bordure autour du TextField
prefixIcon: Icon(Icons.person), // Ajoute une icône avant le texte
),
)
keyboardType
La propriété keyboardType
permet de spécifier le type de clavier qui sera affiché lorsque l’utilisateur tape dans le TextField
. Par exemple, si vous attendez une entrée numérique ou une adresse e-mail, vous pouvez ajuster le clavier pour correspondre.
TextField(
keyboardType: TextInputType.emailAddress, // Affiche un clavier adapté aux emails
decoration: InputDecoration(
labelText: 'Email',
),
)
Quelques valeurs courantes :
- TextInputType.text : Le clavier par défaut pour entrer du texte.
- TextInputType.number : Pour les entrées numériques.
- TextInputType.emailAddress : Pour saisir une adresse e-mail.
obscureText
Si vous voulez cacher le texte saisi dans le TextField
, par exemple pour un mot de passe, vous pouvez utiliser la propriété obscureText
.
TextField(
obscureText: true, // Cache le texte pour les champs de mot de passe
decoration: InputDecoration(
labelText: 'Mot de passe',
),
)
Lorsque obscureText
est défini sur true
, le texte est masqué par des points ou des étoiles pour des raisons de confidentialité. Vous pouvez ajouter un bouton qui change son état à false, pour montrer le texte quand l’utilisateur clique dessus.
maxLength
La propriété maxLength
vous permet de limiter le nombre de caractères que l’utilisateur peut entrer dans le champ de texte.
TextField(
maxLength: 20, // Limite à 20 caractères
decoration: InputDecoration(
labelText: 'Nom d\'utilisateur',
),
)
onChanged
La propriété onChanged
permet d’exécuter une fonction chaque fois que le texte dans le TextField
change. Cela peut être utile pour des validations en temps réel ou pour mettre à jour l’interface en fonction de ce qui est saisi.
TextField(
onChanged: (text) {
print('Le texte a changé : $text'); // Affiche le texte à chaque changement
},
decoration: InputDecoration(
labelText: 'Recherche',
),
)
Définir l’action du clavier
La propriété textInputAction
permet de spécifier l’action du clavier qui s’affiche lorsque l’utilisateur interagit avec un champ de texte. Elle détermine le type de bouton que l’on verra dans la barre d’outils du clavier (comme « Entrée », « Suivant », « Retour », etc.). Cette action peut être utilisée pour faciliter la navigation entre différents champs de texte ou exécuter des actions spécifiques.
Vous pouvez définir cette propriété en l’associant à une valeur de l’énumération TextInputAction
. Les valeurs les plus courantes sont TextInputAction.done
, TextInputAction.next
, TextInputAction.go
, etc. Par exemple :
TextField(
textInputAction: TextInputAction.next, // Passe au champ suivant quand on appuie sur entrer
onChanged: (text) {
print('Le texte est : $text');
},
)
Les différentes actions possibles sont les suivante :
-
TextInputAction.done
: Ce bouton indique que l’utilisateur a terminé la saisie. Le bouton peut afficher « Terminer », « OK » ou « Fermer » en fonction de la plateforme. -
TextInputAction.go
: Utilisé quand une action doit être effectuée, comme soumettre un formulaire ou effectuer une recherche. Sur le bouton, on verra souvent « Go », « Lancer », ou « Exécuter ». -
TextInputAction.next
: C’est l’action pour passer au champ suivant dans un formulaire. Le bouton affichera généralement « Suivant ». -
TextInputAction.previous
: Utilisé pour revenir au champ précédent. Le bouton affiche souvent « Précédent » ou « Retour ». -
TextInputAction.search
: Cette action est souvent utilisée dans des champs de recherche. Le bouton peut afficher « Rechercher », « Chercher », ou parfois l’icône de la loupe. -
TextInputAction.send
: Utilisé pour envoyer un message dans des applications de messagerie. Le bouton sera souvent « Envoyer » ou parfois une icône d’envoi, comme une flèche.
Réaliser une action lors de la soumission du champ
Vous pouvez exécuter une action lorsque l’utilisateur soumet un champ de texte, par exemple en appuyant sur « Done » ou « Entrée » sur le clavier. Avec TextField, utilisez onSubmitted, et avec TextFormField, utilisez onFieldSubmitted. La propriété textInputAction définit la touche du clavier, comme TextInputAction.done pour « Valider » ou TextInputAction.next pour passer au champ suivant.
Voici un exemple tout simple avec le widget TextField :
TextField(
textInputAction: TextInputAction.done,
onSubmitted: (value) {
print('Texte soumis : $value');
},
decoration: InputDecoration(hintText: 'Entrez votre texte'),
)
Et voici un autre exemple avec le widget TextFormField :
Form(
key: GlobalKey<FormState>(),
child: TextFormField(
textInputAction: TextInputAction.done,
onFieldSubmitted: (value) {
if (Form.of(context).validate()) {
print('Texte soumis : $value');
}
},
validator: (value) => value!.isEmpty ? 'Champ requis' : null,
decoration: InputDecoration(hintText: 'Entrez votre texte'),
),
)
Conclusion
Le Textfield est un widget très puissant qui va être utilisé dans bon nombre d’applications. Permettre à l’utilisateur d’entrer des informations et de les stocker quelque part pour pouvoir les afficher en temps réel est à la base de presque toutes les applications mobiles.
Maintenant que vous savez utiliser les widgets de base de Flutter, pourquoi ne pas apprendre à transferer des variables et des fonctions, d’un widget vers un autre, pour les utiliser à plusieurs endroits ?