Lorsque vous créez divers formulaires (par exemple : inscription ou connexion) sur Flutter, vous ne vous souciez pas de personnaliser les composants, car vous pouvez modifier n'importe quel champ de formulaire en fonction de votre style.
En plus de la personnalisation, Flutter fournit des fonctionnalités de gestion des erreurs et de validation des champs de formulaire.
Et aujourd'hui, nous allons essayer de traiter ce sujet avec un petit exemple.
Eh bien, allons-y !
Notre plan
Partie 1 - introduction au développement, première annexe, notion d'état ;
Partie 2 - fichier pubspec.yaml et utilisation de flutter sur la ligne de commande ;
Partie 3 - BottomNavigationBar et Navigator ;
Partie 4 - MVC. Nous utiliserons ce modèle particulier comme l'un des plus simples ;
Partie 5 - paquet http. Création de la classe Repository, premières demandes, listing des posts ;
Partie 6 (article actuel) - Travailler avec des formulaires, des champs de texte et créer un article.
Partie 7 - travailler avec des images, afficher des images sous forme de grille, recevoir des images du réseau, ajouter les vôtres à l'application;
Partie 8 - créer votre propre thème, ajouter des polices et des animations personnalisées ;
Partie 9 - un peu sur les tests;
Création de formulaire : ajout d'un article
Tout d'abord, HomePage
ajoutons un bouton à notre page par lequel nous ajouterons un nouveau message :
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Post List Page"),
),
body: _buildContent(),
// FloatingActionButton
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
},
),
);
}
Ensuite, créons une nouvelle page dans le fichier post_add_page.dart
:
import 'package:flutter/material.dart';
class PostDetailPage extends StatefulWidget {
@override
_PostDetailPageState createState() => _PostDetailPageState();
}
class _PostDetailPageState extends State<PostDetailPage> {
// TextEditingController'
final TextEditingController titleController = TextEditingController();
final TextEditingController contentController = TextEditingController();
// _formKey
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Post Add Page"),
actions: [
// AppBar
IconButton(
icon: Icon(Icons.check),
onPressed: () {
//
if (_formKey.currentState!.validate()) {
// c
}
},
)
],
),
body: Padding(
padding: EdgeInsets.all(15),
child: _buildContent(),
),
);
}
Widget _buildContent() {
//
return Form(
key: _formKey,
//
child: Column(
children: [
//
TextFormField(
// ,
// (hint)
decoration: InputDecoration(
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.face),
hintText: ""
),
// TextEditingController
controller: titleController,
// validator - ,
// null
//
validator: (value) {
// 2
if (value == null || value.isEmpty) {
return " ";
}
if (value.length < 3) {
return " 3 ";
}
return null;
},
),
//
SizedBox(height: 10),
// Expanded ,
//
Expanded(
child: TextFormField(
// maxLines: null expands: true
//
maxLines: null,
expands: true,
textAlignVertical: TextAlignVertical.top,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "",
),
// TextEditingController
controller: contentController,
//
validator: (value) {
if (value == null || value.isEmpty) {
return " ";
}
return null;
},
),
)
],
),
);
}
}
N'oubliez pas d'ajouter une transition à la page du formulaire :
floatingActionButton: FloatingActionButton( child: Icon(Icons.add), onPressed: () { Navigator.push(context, MaterialPageRoute( builder: (context) => PostDetailPage() )); }, ),
Lancez et cliquez sur le bouton :
! .
. , .
100%- Flutter Dart :
Flutter 2.0.6
Dart SDK version: 2.12.3
null safety. , .
null safety. :
// ! , 100%
// currentState null
_formKey.currentState!.validate()
null safety Dart , .
POST .
POST
POST, , HTTP .
Post
:
class Post {
// private
//
final int? _userId;
final int? _id;
final String? _title;
final String? _body;
// getters
//
int? get userId => _userId;
int? get id => _id;
String? get title => _title;
String? get body => _body;
//
Post(this._userId, this._id, this._title, this._body);
// toJson() Post JSON
String toJson() {
return json.encode({
"title": _title,
"content": _body
});
}
// Dart
// Post.fromJson(json) -
//
// , dynamic
// : String, int, double ..
Post.fromJson(Map<String, dynamic> json) :
this._userId = json["userId"],
this._id = json["id"],
this._title = json["title"],
this._body = json["body"];
}
//
abstract class PostAdd {}
//
class PostAddSuccess extends PostAdd {}
//
class PostAddFailure extends PostAdd {}
Repository
:
//
Future<PostAdd> addPost(Post post) async {
final url = Uri.parse("$SERVER/posts");
// POST ,
// JSON
final response = await http.post(url, body: post.toJson());
//
if (response.statusCode == 201) {
// ,
return PostAddSuccess();
} else {
//
return PostAddFailure();
}
}
PostController
:
//
// addPost callback,
//
void addPost(Post post, void Function(PostAdd) callback) async {
try {
final result = await repo.addPost(post);
//
callback(result);
} catch (error) {
//
callback(PostAddFailure());
}
}
PostAddPage
:
class PostDetailPage extends StatefulWidget {
@override
_PostDetailPageState createState() => _PostDetailPageState();
}
// StateMVC
class _PostDetailPageState extends StateMVC {
// _controller null
PostController? _controller;
// PostController
_PostDetailPageState() : super(PostController()) {
_controller = controller as PostController;
}
// TextEditingController'
final TextEditingController titleController = TextEditingController();
final TextEditingController contentController = TextEditingController();
// _formKey
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Post Add Page"),
actions: [
// AppBar
IconButton(
icon: Icon(Icons.check),
onPressed: () {
//
if (_formKey.currentState!.validate()) {
//
// TextEditingController'
final post = Post(
-1, -1, titleController.text, contentController.text
);
//
_controller!.addPost(post, (status) {
if (status is PostAddSuccess) {
//
//
//
Navigator.pop(context, status);
} else {
//
// SnackBar -
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(" "))
);
}
});
}
},
)
],
),
body: Padding(
padding: EdgeInsets.all(15),
child: _buildContent(),
),
);
}
Widget _buildContent() {
//
return Form(
key: _formKey,
//
child: Column(
children: [
//
TextFormField(
// ,
// (hint)
decoration: InputDecoration(
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.face),
hintText: ""
),
// TextEditingController
controller: titleController,
// validator - ,
// null
//
validator: (value) {
// 2
if (value == null || value.isEmpty) {
return " ";
}
if (value.length < 3) {
return " 3 ";
}
return null;
},
),
//
SizedBox(height: 10),
// Expanded ,
//
Expanded(
child: TextFormField(
// maxLines: null expands: true
//
maxLines: null,
expands: true,
textAlignVertical: TextAlignVertical.top,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "",
),
// TextEditingController
controller: contentController,
//
validator: (value) {
if (value == null || value.isEmpty) {
return " ";
}
return null;
},
),
)
],
),
);
}
}
:
,
, .
, PostListPage
:
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
// then Future
//
Navigator.push(context, MaterialPageRoute(
builder: (context) => PostDetailPage()
)).then((value) {
if (value is PostAddSuccess) {
// SnackBar -
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(" "))
);
}
});
},
),
:
J'espère vous avoir convaincu que travailler avec des formulaires dans Flutter est très simple et ne nécessite presque aucun effort.
La plupart du code fait une requête POST au serveur et gère les erreurs.
Liens utiles
Bon code à tous)