Flutter でさまざまなフォーム (登録やログインなど) を作成する場合、スタイルに合わせてフォーム フィールドを変更できるため、コンポーネントをカスタマイズする必要はありません。
カスタマイズに加えて、Flutter はエラー処理とフォーム フィールドの検証機能を提供します。
そして今日、私たちは小さな例でこのトピックに対処しようとします。
では、行きましょう!
私たちの計画
パート 1 - 開発の紹介、最初の付録、状態の概念。
パート 2 - pubspec.yaml ファイルとコマンド ラインでのフラッターの使用。
パート 3 - BottomNavigationBar とナビゲーター。
パート 4 - MVC。この特定のパターンを最も単純なものの 1 つとして使用します。
パート 5 - http パッケージ。Repository クラスの作成、最初のリクエスト、投稿のリスト。
パート 6 (現在の記事) - フォーム、テキスト フィールドの操作、および投稿の作成。
パート 7 - 画像の操作、グリッドの形式での画像の表示、ネットワークからの画像の受信、独自の画像のアプリケーションへの追加。
パート 8 - 独自のテーマを作成し、カスタム フォントとアニメーションを追加します。
パート 9 - テストについて少し。
フォームの作成: 投稿の追加
まず、HomePage
新しい投稿を追加するためのボタンをページに追加しましょう。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Post List Page"),
),
body: _buildContent(),
// FloatingActionButton
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
},
),
);
}
次に、ファイルに新しいページを作成しましょう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;
},
),
)
],
),
);
}
}
フォーム ページにトランジションを追加することを忘れないでください。
floatingActionButton: FloatingActionButton( child: Icon(Icons.add), onPressed: () { Navigator.push(context, MaterialPageRoute( builder: (context) => PostDetailPage() )); }, ),
ボタンを起動してクリックします。
! .
. , .
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(" "))
);
}
});
},
),
:
Flutter でのフォームの操作は非常に簡単で、ほとんど労力を必要としないことを理解していただければ幸いです。
コードのほとんどは、サーバーに POST リクエストを行い、エラーを処理しています。
便利なリンク
みんな良いコード)