Formulario con validación en Flutter: ejercicio resuelto

  2 minutos

Si necesitas formulario con validación en Flutter, este ejemplo te ayuda a validar email y password antes de enviar.

Construye un formulario con:

  • campo email,
  • campo password,
  • validaciones,
  • botón enviar con feedback.
import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(home: LoginFormPage()));

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

  @override
  State<LoginFormPage> createState() => _LoginFormPageState();
}

class _LoginFormPageState extends State<LoginFormPage> {
  final _formKey = GlobalKey<FormState>();
  final _emailCtrl = TextEditingController();
  final _passCtrl = TextEditingController();

  @override
  void dispose() {
    _emailCtrl.dispose();
    _passCtrl.dispose();
    super.dispose();
  }

  void submit() {
    if (_formKey.currentState!.validate()) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Formulario valido: ${_emailCtrl.text}')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Formulario Flutter')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Form(
          key: _formKey,
          child: Column(
            children: [
              TextFormField(
                controller: _emailCtrl,
                decoration: const InputDecoration(labelText: 'Email'),
                validator: (value) {
                  if (value == null || value.isEmpty) return 'Email obligatorio';
                  if (!value.contains('@')) return 'Email no valido';
                  return null;
                },
              ),
              TextFormField(
                controller: _passCtrl,
                decoration: const InputDecoration(labelText: 'Password'),
                obscureText: true,
                validator: (value) {
                  if (value == null || value.length < 6) return 'Minimo 6 caracteres';
                  return null;
                },
              ),
              const SizedBox(height: 16),
              ElevatedButton(onPressed: submit, child: const Text('Enviar')),
            ],
          ),
        ),
      ),
    );
  }
}

El botón solo permite enviar cuando ambos campos cumplen reglas básicas.

  • No usar GlobalKey<FormState>.
  • Validar en onChanged sin control.
  • Olvidar liberar TextEditingController.

Es el bloque base para login, registro, checkout y formularios internos de negocio.

Normalmente Form junto con TextFormField y validadores por campo.

En los validadores de cada campo, devolviendo mensajes claros y breves.

Sí. Puedes extraer reglas y reutilizar validadores en pantallas grandes.