これまでTextFieldを使って入力フォームを作成してきましたが、
ログイン画面などでは「入力チェック(バリデーション)」が必要になります。
その場合は、TextFormFieldを使用すると簡単に実装できます。
TextFieldからTextFormFieldへ変更し、バリデーション対応したフォームを作成します。
TextFieldはシンプルな入力用ですが、
TextFormFieldはFormと組み合わせることで、入力チェックを簡単に実装できます。
実装イメージ
-
TextFormFieldに変更する -
validatorを追加する -
Formで全体を囲む -
GlobalKeyでフォームを管理する
EmailFieldの変更
class EmailField extends StatelessWidget {
final Function(String) onChanged;
const EmailField({super.key, required this.onChanged});
@override
Widget build(BuildContext context) {
return TextFormField(
decoration: InputDecoration(
hintText: 'メールアドレス',
prefixIcon: const Icon(Icons.mail),
filled: true,
fillColor: Colors.white.withValues(alpha: 0.6),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
),
keyboardType: TextInputType.emailAddress,
onChanged: onChanged,
validator: (value) {
if (value == null || value.isEmpty) {
return 'メールを入力してください';
}
if (!value.contains('@')) {
return 'メール形式が正しくありません';
}
return null;
},
);
}
}
PasswordFieldの変更
class PasswordField extends StatefulWidget {
final Function(String) onChanged;
const PasswordField({super.key, required this.onChanged});
@override
State<PasswordField> createState() => _PasswordFieldState();
}
class _PasswordFieldState extends State<PasswordField> {
bool obscure = true;
@override
Widget build(BuildContext context) {
return TextFormField(
obscureText: obscure,
onChanged: widget.onChanged,
decoration: InputDecoration(
hintText: 'パスワード',
prefixIcon: const Icon(Icons.lock),
suffixIcon: IconButton(
icon: Icon(
obscure ? Icons.visibility_off : Icons.visibility,
),
onPressed: () {
setState(() {
obscure = !obscure;
});
},
),
filled: true,
fillColor: Colors.white.withValues(alpha: 0.6),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'パスワードを入力してください';
}
if (value.length < 6) {
return '6文字以上で入力してください';
}
return null;
},
);
}
}
変更内容
TextFormFieldに変更。
validatorにバリデーションの内容を追加。
Formの追加
final _formKey = GlobalKey<FormState>();
return Form(
key: _formKey,
child: Column(
children: [
EmailField(onChanged: (value) {}),
PasswordField(onChanged: (value) {}),
],
),
);
TextFormFieldを使用する場合は、Formで全体を囲みます。
バリデーションの実行
if (_formKey.currentState!.validate()) {
// バリデーションOK時の処理
}
ログインボタン押下時に、validate()を呼び出します。
以上で、バリデーション対応のフォームの作成は完了です。
シンプルに実装することができました。
