MENU

Flutterでフォームの入力エラーを表示する方法|TextFormFieldの基本

Flutterでフォームの入力エラーを表示する方法|TextFormFieldの基本

Flutter 入力エラー 表示は、Formで入力欄をまとめ、TextFormFieldのvalidatorで条件を決め、送信時にvalidate()を呼び出すと実装できます。入力が空なら「入力してください」のようなメッセージを表示し、問題がなければ保存やAPI送信へ進めます。

この記事では、名前入力を例に、最小構成のコード、入力中にエラーを表示する方法、エラーが出ないときの確認点まで説明します。

初心者の疑問: TextFieldを使っているのに、なぜ入力エラーが表示されないのでしょうか?

目次

Flutterの入力エラー表示に使う3つの部品

まず、役割を分けて考えると理解しやすくなります。

部品役割
Form複数の入力欄をまとめて管理する
TextFormField入力欄と検証ルールを持つ
validator入力が正しいか判定し、エラー文またはnullを返す

TextFieldにも見た目のエラー表示機能はありますが、フォーム全体をまとめて検証するならTextFormFieldの方が扱いやすい構成です。Flutter公式のフォーム検証でも、この組み合わせが使われています。

validatorはエラーがあるときに文字列を返し、問題がないときは必ずnullを返します。

最小構成で入力エラーを表示する

次の例では、名前が空のまま「送信」ボタンを押すと、入力欄の下にエラーメッセージを表示します。

import 'package:flutter/material.dart';

class ProfileForm extends StatefulWidget {
  const ProfileForm({super.key});

  @override
  State<ProfileForm> createState() => _ProfileFormState();
}

class _ProfileFormState extends State<ProfileForm> {
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          TextFormField(
            decoration: const InputDecoration(
              labelText: '名前',
              border: OutlineInputBorder(),
            ),
            validator: (value) {
              if (value == null || value.trim().isEmpty) {
                return '名前を入力してください';
              }
              return null;
            },
          ),
          const SizedBox(height: 16),
          ElevatedButton(
            onPressed: () {
              if (_formKey.currentState!.validate()) {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('入力内容を確認しました')),
                );
              }
            },
            child: const Text('送信'),
          ),
        ],
      ),
    );
  }
}

コードの流れ

  1. GlobalKey<FormState>を作り、フォームの状態を参照できるようにします。
  2. Formにkey: _formKeyを指定します。
  3. TextFormFieldのvalidatorで入力条件を決めます。
  4. ボタンで_formKey.currentState!.validate()を呼び出します。
  5. trueなら保存や送信、falseならエラー表示のまま止めます。

validate()を呼ぶと、同じForm内にある各フィールドのvalidatorが実行されます。エラーが1つでもあればfalseになり、該当するメッセージが画面に表示されます。

初心者の疑問: validatorを書いただけで検証されますか? validatorは判定ルールを登録するだけです。送信ボタンなどからvalidate()を呼ぶことで、実際の検証とエラー表示が始まります。

よく使う入力チェックの書き方

空欄を禁止する

空文字だけでなく、前後に空白しかない入力も拒否したい場合はtrim()を使います。

validator: (value) {
  if (value == null || value.trim().isEmpty) {
    return '入力してください';
  }
  return null;
},

メールアドレスの形式を確認する

複雑な正規表現を最初から作るより、まずは「空欄ではない」「@を含む」程度の簡単な条件から始めると、初心者でも調整しやすくなります。

validator: (value) {
  final email = value?.trim() ?? '';
  if (email.isEmpty) {
    return 'メールアドレスを入力してください';
  }
  if (!email.contains('@')) {
    return 'メールアドレスの形式を確認してください';
  }
  return null;
},

注意: 画面上の入力チェックだけで、メールアドレスの存在や本人確認まで保証できるわけではありません。サーバー側でも必要な検証を行ってください。

文字数に上限を設ける

validator: (value) {
  final text = value?.trim() ?? '';
  if (text.isEmpty) {
    return 'コメントを入力してください';
  }
  if (text.length > 200) {
    return '200文字以内で入力してください';
  }
  return null;
},

日本語を含む入力では、必要に応じてcharactersパッケージなど、ユーザーが認識する文字単位での数え方も検討します。単純なlengthが要件に合うかは、アプリの仕様を確認してください。

入力中にエラーを表示する方法

初期状態では、送信ボタンを押すまでエラーを表示しない設計が自然です。一方で、入力を始めた後はすぐに間違いを知らせたい場合、autovalidateModeを設定できます。

Form(
  key: _formKey,
  autovalidateMode: AutovalidateMode.onUserInteraction,
  child: Column(
    children: [
      TextFormField(
        validator: (value) {
          if (value == null || value.trim().isEmpty) {
            return '名前を入力してください';
          }
          return null;
        },
      ),
    ],
  ),
)

AutovalidateMode.onUserInteractionは、ユーザーが操作した後に自動検証する設定です。画面を開いた直後から赤いエラーを並べるより、入力を始めてから知らせる方が、フォームの印象が分かりやすくなります。

比較ポイント: 送信時だけ検証する方法は落ち着いて入力できます。入力中に検証する方法は間違いに早く気づけます。入力項目の重要度や画面の長さに合わせて選びましょう。

入力エラーが表示されないときの確認点

`TextField`ではなく`TextFormField`を使っているか

validatorはTextFormFieldに指定します。TextFieldを使い続ける場合は、errorTextを状態変数で管理する別の実装が必要です。

`Form`と入力欄が同じ階層にあるか

TextFormFieldが対象のFormの子孫になっていなければ、そのフォームのvalidate()で検証されません。Formの中にTextFormFieldを置いているか確認します。

ボタンで`validate()`を呼んでいるか

ボタンのonPressedが空だったり、別のキーを参照していたりすると、エラー表示は始まりません。

失敗例: build()の中で毎回GlobalKey<FormState>()を作ると、ボタンを押したときにフォームとキーの対応が崩れることがあります。 改善例: Stateクラスのフィールドとしてfinal _formKey = GlobalKey<FormState>();を1回だけ作り、build()では同じキーを使います。

`validator`が常に`null`を返していないか

条件分岐の後に必ずreturn nullがあるか、入力値を確認しています。例えば、次のコードでは常に問題なしと判定されます。

validator: (value) {
  return null;
},

複数の入力欄を検証する場合

メールアドレスとパスワードのように入力欄が複数ある場合も、同じFormの中にTextFormFieldを追加します。送信時のvalidate()は、それぞれのvalidatorを順番に実行します。

パスワードの確認欄など、2つの値を比較する場合は、TextEditingControllerで入力値を取得してから比較します。ただし、比較処理が複雑になったら、検証ロジックを別メソッドに分けると読みやすくなります。

チェックリスト: Formにキーを指定した、入力欄はTextFormFieldにした、空欄時のメッセージを書いた、validate()を送信処理の前に呼んだ、成功時だけ保存する流れにした。

関連記事と次にやること

入力欄そのものの作り方を先に確認したい場合は、Flutterでフォーム入力を実装する方法も参考になります。今回の検証処理を追加したら、次はTextEditingControllerで値を取得し、実際の保存処理につなげてみましょう。

次にやること: まず名前欄を1つ作り、空欄で送信したときにエラーメッセージが表示されることを確認してください。

まとめ

Flutterの入力エラー表示は、Form、TextFormField、validator、validate()の4点を組み合わせると実装できます。最初は空欄チェックだけで動かし、必要に応じてメール形式や文字数、入力中の自動検証を追加すると安全です。

入力チェックが動かないときは、TextFormFieldが対象のForm内にあるか、同じGlobalKeyでvalidate()を呼んでいるか、validatorがエラーメッセージを返しているかを順番に確認しましょう。

参考にした公式情報

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

meibuのアバター meibu 中年ブロガー

【このブログを書いている人】
こんにちは、meibuです!
読者の「ちょっと気になる」「でも難しそう…」をやさしく解決したくてこのブログを始めました。

🔹プロフィールまとめ
◎ 本業は運送業の管理職
 → 現場からマネジメントまで幅広く経験

● 趣味はパソコン・ランニング・情報収集

●興味のあるテーマ:
 副業 / ChatGPT

● 発信スタイルは…
 → 「初心者にもわかりやすく」+「図解・たとえ話も使って解説」

● ブログの目的:
 日常に“ちょっと得する”選択肢を増やすこと
管理職の悩みを最近少し書いています

🔸こんな人に読んでほしい!
ChatGPTってなに?使い方がわからない方
管理職の職位に悩んでいる人
忙しいけど、自分の未来のために動きたい方

● 「読んでよかった!」と思える情報を、これからもコツコツ更新していきます!
当ブログはアフェリエイト広告を利用しています。

コメント

コメントする

CAPTCHA


目次