Kodokon kodokon.com

Formulare: TextField, Controller und Validierung

Steuere deine Eingabefelder mit TextEditingController und validiere jede Eingabe auf einmal, dank Form und TextFormField.

9 Min. · 3 Fragen

Diese Lektion in Kodokon öffnen

Ein Eingabefeld ohne Controller ist eine Blackbox. TextEditingController gibt dir die Kontrolle: Lies controller.text jederzeit aus, fülle das Feld vor, leere es nach dem Absenden oder lausche mit addListener auf jeden Tastendruck. Der Controller wird in einem State erstellt, niemals in build - sonst würde er bei jedem Rebuild neu erzeugt.

DART
import 'package:flutter/material.dart';

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

  @override
  State<NicknameField> createState() =>
      _NicknameFieldState();
}

class _NicknameFieldState extends State<NicknameField> {
  final _controller = TextEditingController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: _controller,
      decoration: const InputDecoration(
        labelText: 'Nickname',
        border: OutlineInputBorder(),
      ),
      onSubmitted: (value) => debugPrint(value),
    );
  }
}
Der Controller lebt im State und stirbt in dispose().

Sobald ein Screen mehrere Felder zu prüfen hat, greife zum Trio Form, GlobalKey<FormState> und TextFormField. Jedes Feld beschreibt seine Regel in validator: Die Funktion gibt eine Fehlermeldung zurück oder null, wenn alles in Ordnung ist. Ein Aufruf von validate() auf dem Key löst alle Validatoren auf einmal aus.

DART
import 'package:flutter/material.dart';

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

  @override
  State<SignUpForm> createState() => _SignUpFormState();
}

class _SignUpFormState extends State<SignUpForm> {
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();

  @override
  void dispose() {
    _emailController.dispose();
    super.dispose();
  }

  void _submit() {
    if (_formKey.currentState!.validate()) {
      debugPrint('Email: ${_emailController.text}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          TextFormField(
            controller: _emailController,
            keyboardType: TextInputType.emailAddress,
            decoration: const InputDecoration(
              labelText: 'Email',
            ),
            validator: (value) {
              if (value == null || value.isEmpty) {
                return 'Required field';
              }
              if (!value.contains('@')) {
                return 'Invalid address';
              }
              return null;
            },
          ),
          const SizedBox(height: 16),
          FilledButton(
            onPressed: _submit,
            child: const Text('Create account'),
          ),
        ],
      ),
    );
  }
}
validate() löst jeden Validator des Formulars aus.

Beim Klick auf den Button führt validate() jeden validator aus: Die zurückgegebenen Meldungen erscheinen rot unter den betreffenden Feldern, und die Methode gibt false zurück, wenn mindestens ein Feld ungültig ist. Deine Absende-Logik bleibt also hinter einem einzigen if - es ist unmöglich, ungültige Daten abzuschicken.

Wissenscheck

Stelle sicher, dass du die wichtigsten Punkte dieser Lektion behalten hast.

  1. Wofür ist ein TextEditingController da?
    • Um den Rahmen des Felds zu zeichnen
    • Um den Text des Felds zu lesen und zu ändern und auf seine Änderungen zu lauschen
    • Um E-Mail-Adressen automatisch zu validieren
    • Um die Tastatur zu schließen
  2. Was soll ein validator zurückgeben, wenn der Wert gültig ist?
    • true
    • Eine leere Zeichenkette
    • null
    • Den Wert selbst
  3. Warum sollte man _controller.dispose() in der dispose()-Methode des State aufrufen?
    • Um das Feld auf dem Bildschirm zu leeren
    • Um Ressourcen freizugeben und Speicherlecks zu vermeiden
    • Um das Formular abzuschicken