入力フォームのエラーメッセージの表示の仕方
公式ドキュメントのはこちら
https://docs.flutter.dev/cookbook/forms/validation
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
const appTitle = 'Form Validation Demo';
return MaterialApp(
title: appTitle,
home: Scaffold(
appBar: AppBar(
title: const Text(appTitle),
),
body: const MyCustomForm(),
),
);
}
}
// Create a Form widget.
class MyCustomForm extends StatefulWidget {
const MyCustomForm({Key? key}) : super(key: key);
@override
MyCustomFormState createState() {
return MyCustomFormState();
}
}
// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
// Create a global key that uniquely identifies the Form widget
// and allows validation of the form.
//
// Note: This is a GlobalKey<FormState>,
// not a GlobalKey<MyCustomFormState>.
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextFormField(
// The validator receives the text that the user has entered.
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: ElevatedButton(
onPressed: () {
// Validate returns true if the form is valid, or false otherwise.
if (_formKey.currentState!.validate()) {
// If the form is valid, display a snackbar. In the real world,
// you'd often call a server or save the information in a database.
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
}
},
child: const Text('Submit'),
),
),
],
),
);
}
}
Udemyで学習したLogin画面の入力フォームの作り方だと、正規表現が使ってあった?
正規表現は難しい???
動くサンプルがあった方が勉強になると思うので、記録を残しておく。
main.dart
import 'package:finstagram/pages/login_page.dart';
import 'package:finstagram/pages/register_page.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Finstagram',
theme: ThemeData(
primarySwatch: Colors.red,
),
// ルートを指定しないとエラーになる!
initialRoute: 'login',
// Mapで書く
routes: {
'register': (context) => RegisterPage(),
'login': (context) => LoginPage(),
},
);
}
}
login_page.dart
import 'package:flutter/material.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
double? _deviceHeight, _deviceWidth;
// ログとフォームキーをとる
final GlobalKey<FormState> _loginFormKey = GlobalKey<FormState>();
String? _email; // emailの変数
String? _password; // passwordの変数
@override
Widget build(BuildContext context) {
_deviceHeight = MediaQuery.of(context).size.height; // 高さを設定
_deviceWidth = MediaQuery.of(context).size.width; // 幅を設定
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: _deviceWidth! * 0.05),
child: Center(
child: Column(
// 水平パディング
mainAxisAlignment: MainAxisAlignment.spaceAround,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_titleWidget(),
_loginForm(),
_loginButton(),
],
),
),
)),
);
}
// タイトル関数
Widget _titleWidget() {
return const Text(
"Finstagram",
style: TextStyle(
color: Colors.black, fontSize: 25, fontWeight: FontWeight.w600),
);
}
// 入力フォーム関数
Widget _loginForm() {
return Container(
height: _deviceHeight! * 0.20,
child: Form(
key: _loginFormKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_emailTextField(),
_passwordTextField(),
],
)),
);
}
// email入力をする関数
Widget _emailTextField() {
return TextFormField(
decoration: const InputDecoration(hintText: "Email..."),
onSaved: (_value) {
setState(() {
_email = _value;
});
},
// 正規表現でバリデーションチェック
validator: (_value) {
bool _result = _value!.contains(
RegExp(
r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"),
);
return _result ? null : "Please enter a valid email";
},
);
}
// password入力をする関数
Widget _passwordTextField() {
return TextFormField(
obscureText: true, // パスワードを隠す
decoration: const InputDecoration(hintText: "password..."),
onSaved: (_value) {
setState(() {
_password = _value;
});
},
// パスワードを6桁入力するバリデーション
validator: (_value) => _value!.length > 6
? null
: "Please enter a password greter than 6 characters.",
);
}
// ログインボタン関数
Widget _loginButton() {
return MaterialButton(
onPressed: _loginUser,
minWidth: _deviceWidth! * 0.70,
height: _deviceHeight! * 0.06,
color: Colors.red,
child: const Text(
"Login",
style: TextStyle(
color: Colors.white, fontSize: 25, fontWeight: FontWeight.w600),
),
);
}
// ユーザーログイン関数
void _loginUser() {
if (_loginFormKey.currentState!.validate()) {
// フォームフィールドの情報を変数に保存
_loginFormKey.currentState!.save();
}
}
}
ragister_page.dart
import 'package:flutter/material.dart';
class RegisterPage extends StatefulWidget {
const RegisterPage({ Key? key }) : super(key: key);
@override
State<RegisterPage> createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(color: Colors.red,),
);
}
}