En esta sección, aprenderemos sobre los widgets de entrada y formularios en Flutter. Estos widgets son esenciales para crear aplicaciones interactivas que requieran la entrada de datos por parte del usuario. Cubriremos los siguientes temas:

  1. TextField
  2. Form
  3. FormField
  4. Checkbox
  5. Radio
  6. Switch
  7. DropdownButton
  8. ElevatedButton

  1. TextField

El widget TextField es el más común para la entrada de texto. Permite a los usuarios escribir y editar texto.

Ejemplo Básico de TextField

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('TextField Example')),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: TextField(
            decoration: InputDecoration(
              border: OutlineInputBorder(),
              labelText: 'Enter your name',
            ),
          ),
        ),
      ),
    );
  }
}

Explicación

  • TextField: Widget para la entrada de texto.
  • InputDecoration: Proporciona decoraciones como bordes y etiquetas para el TextField.
  • OutlineInputBorder: Añade un borde alrededor del TextField.
  • labelText: Texto que se muestra como etiqueta dentro del TextField.

  1. Form

El widget Form agrupa varios widgets de entrada y permite validarlos de manera conjunta.

Ejemplo Básico de Form

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Form Example')),
        body: MyCustomForm(),
      ),
    );
  }
}

class MyCustomForm extends StatefulWidget {
  @override
  _MyCustomFormState createState() => _MyCustomFormState();
}

class _MyCustomFormState extends State<MyCustomForm> {
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          TextFormField(
            decoration: InputDecoration(
              labelText: 'Enter your name',
            ),
            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: () {
                if (_formKey.currentState!.validate()) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Processing Data')),
                  );
                }
              },
              child: Text('Submit'),
            ),
          ),
        ],
      ),
    );
  }
}

Explicación

  • Form: Widget que agrupa y gestiona varios widgets de entrada.
  • GlobalKey<FormState>: Clave global para identificar el estado del formulario.
  • TextFormField: Similar a TextField, pero con validación integrada.
  • validator: Función que valida la entrada del usuario.
  • ElevatedButton: Botón que, al ser presionado, valida el formulario.

  1. FormField

El widget FormField es una clase base para widgets que se utilizan dentro de un Form.

Ejemplo Básico de FormField

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('FormField Example')),
        body: MyCustomForm(),
      ),
    );
  }
}

class MyCustomForm extends StatefulWidget {
  @override
  _MyCustomFormState createState() => _MyCustomFormState();
}

class _MyCustomFormState extends State<MyCustomForm> {
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          FormField<String>(
            builder: (FormFieldState<String> state) {
              return TextFormField(
                decoration: InputDecoration(
                  labelText: 'Enter your name',
                ),
                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: () {
                if (_formKey.currentState!.validate()) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Processing Data')),
                  );
                }
              },
              child: Text('Submit'),
            ),
          ),
        ],
      ),
    );
  }
}

Explicación

  • FormField: Clase base para widgets dentro de un Form.
  • FormFieldState: Estado del FormField.

  1. Checkbox

El widget Checkbox permite a los usuarios seleccionar o deseleccionar una opción.

Ejemplo Básico de Checkbox

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Checkbox Example')),
        body: MyCheckboxWidget(),
      ),
    );
  }
}

class MyCheckboxWidget extends StatefulWidget {
  @override
  _MyCheckboxWidgetState createState() => _MyCheckboxWidgetState();
}

class _MyCheckboxWidgetState extends State<MyCheckboxWidget> {
  bool _isChecked = false;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: CheckboxListTile(
        title: Text('Accept Terms and Conditions'),
        value: _isChecked,
        onChanged: (bool? value) {
          setState(() {
            _isChecked = value!;
          });
        },
      ),
    );
  }
}

Explicación

  • CheckboxListTile: Combina un Checkbox con un ListTile.
  • value: Estado actual del Checkbox.
  • onChanged: Función que se llama cuando el estado del Checkbox cambia.

  1. Radio

El widget Radio permite a los usuarios seleccionar una opción de un conjunto de opciones.

Ejemplo Básico de Radio

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Radio Example')),
        body: MyRadioWidget(),
      ),
    );
  }
}

class MyRadioWidget extends StatefulWidget {
  @override
  _MyRadioWidgetState createState() => _MyRadioWidgetState();
}

class _MyRadioWidgetState extends State<MyRadioWidget> {
  String? _selectedOption = 'Option 1';

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        ListTile(
          title: Text('Option 1'),
          leading: Radio<String>(
            value: 'Option 1',
            groupValue: _selectedOption,
            onChanged: (String? value) {
              setState(() {
                _selectedOption = value;
              });
            },
          ),
        ),
        ListTile(
          title: Text('Option 2'),
          leading: Radio<String>(
            value: 'Option 2',
            groupValue: _selectedOption,
            onChanged: (String? value) {
              setState(() {
                _selectedOption = value;
              });
            },
          ),
        ),
      ],
    );
  }
}

Explicación

  • Radio: Widget para seleccionar una opción.
  • value: Valor de la opción.
  • groupValue: Valor del grupo de opciones.
  • onChanged: Función que se llama cuando se selecciona una opción.

  1. Switch

El widget Switch permite a los usuarios alternar entre dos estados, como encendido y apagado.

Ejemplo Básico de Switch

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Switch Example')),
        body: MySwitchWidget(),
      ),
    );
  }
}

class MySwitchWidget extends StatefulWidget {
  @override
  _MySwitchWidgetState createState() => _MySwitchWidgetState();
}

class _MySwitchWidgetState extends State<MySwitchWidget> {
  bool _isSwitched = false;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: SwitchListTile(
        title: Text('Enable Notifications'),
        value: _isSwitched,
        onChanged: (bool value) {
          setState(() {
            _isSwitched = value;
          });
        },
      ),
    );
  }
}

Explicación

  • SwitchListTile: Combina un Switch con un ListTile.
  • value: Estado actual del Switch.
  • onChanged: Función que se llama cuando el estado del Switch cambia.

  1. DropdownButton

El widget DropdownButton permite a los usuarios seleccionar una opción de un menú desplegable.

Ejemplo Básico de DropdownButton

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('DropdownButton Example')),
        body: MyDropdownButtonWidget(),
      ),
    );
  }
}

class MyDropdownButtonWidget extends StatefulWidget {
  @override
  _MyDropdownButtonWidgetState createState() => _MyDropdownButtonWidgetState();
}

class _MyDropdownButtonWidgetState extends State<MyDropdownButtonWidget> {
  String? _selectedItem = 'Item 1';

  @override
  Widget build(BuildContext context) {
    return Center(
      child: DropdownButton<String>(
        value: _selectedItem,
        items: <String>['Item 1', 'Item 2', 'Item 3'].map((String value) {
          return DropdownMenuItem<String>(
            value: value,
            child: Text(value),
          );
        }).toList(),
        onChanged: (String? newValue) {
          setState(() {
            _selectedItem = newValue;
          });
        },
      ),
    );
  }
}

Explicación

  • DropdownButton: Widget para seleccionar una opción de un menú desplegable.
  • value: Valor actual seleccionado.
  • items: Lista de opciones.
  • onChanged: Función que se llama cuando se selecciona una opción.

  1. ElevatedButton

El widget ElevatedButton es un botón elevado que se utiliza para realizar acciones.

Ejemplo Básico de ElevatedButton

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('ElevatedButton Example')),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              print('Button Pressed');
            },
            child: Text('Press Me'),
          ),
        ),
      ),
    );
  }
}

Explicación

  • ElevatedButton: Botón elevado.
  • onPressed: Función que se llama cuando se presiona el botón.
  • child: Contenido del botón, generalmente un Text.

Ejercicio Práctico

Ejercicio

Crea una aplicación que tenga un formulario con los siguientes campos:

  1. Nombre (TextField)
  2. Correo Electrónico (TextField)
  3. Aceptar Términos y Condiciones (Checkbox)
  4. Género (Radio)
  5. País (DropdownButton)
  6. Botón de Enviar (ElevatedButton)

Solución

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Form Example')),
        body: MyCustomForm(),
      ),
    );
  }
}

class MyCustomForm extends StatefulWidget {
  @override
  _MyCustomFormState createState() => _MyCustomFormState();
}

class _MyCustomFormState extends State<MyCustomForm> {
  final _formKey = GlobalKey<FormState>();
  bool _isChecked = false;
  String? _selectedGender = 'Male';
  String? _selectedCountry = 'USA';

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TextFormField(
              decoration: InputDecoration(
                labelText: 'Enter your name',
              ),
              validator: (value) {
                if (value == null || value.isEmpty) {
                  return 'Please enter some text';
                }
                return null;
              },
            ),
            TextFormField(
              decoration: InputDecoration(
                labelText: 'Enter your email',
              ),
              validator: (value) {
                if (value == null || value.isEmpty) {
                  return 'Please enter some text';
                }
                return null;
              },
            ),
            CheckboxListTile(
              title: Text('Accept Terms and Conditions'),
              value: _isChecked,
              onChanged: (bool? value) {
                setState(() {
                  _isChecked = value!;
                });
              },
            ),
            ListTile(
              title: Text('Male'),
              leading: Radio<String>(
                value: 'Male',
                groupValue: _selectedGender,
                onChanged: (String? value) {
                  setState(() {
                    _selectedGender = value;
                  });
                },
              ),
            ),
            ListTile(
              title: Text('Female'),
              leading: Radio<String>(
                value: 'Female',
                groupValue: _selectedGender,
                onChanged: (String? value) {
                  setState(() {
                    _selectedGender = value;
                  });
                },
              ),
            ),
            DropdownButton<String>(
              value: _selectedCountry,
              items: <String>['USA', 'Canada', 'Mexico'].map((String value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: Text(value),
                );
              }).toList(),
              onChanged: (String? newValue) {
                setState(() {
                  _selectedCountry = newValue;
                });
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16.0),
              child: ElevatedButton(
                onPressed: () {
                  if (_formKey.currentState!.validate()) {
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('Processing Data')),
                    );
                  }
                },
                child: Text('Submit'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Explicación

  • Se combinan varios widgets de entrada y un botón de envío dentro de un Form.
  • Se utiliza CheckboxListTile, Radio, DropdownButton, y ElevatedButton para crear un formulario completo.

Conclusión

En esta sección, hemos aprendido sobre los widgets de entrada y formularios en Flutter. Estos widgets son fundamentales para crear aplicaciones interactivas y recolectar datos de los usuarios. Hemos cubierto TextField, Form, FormField, Checkbox, Radio, Switch, DropdownButton, y ElevatedButton, y hemos visto cómo combinarlos en un formulario completo. Con estos conocimientos, estás listo para crear formularios más complejos y manejar la entrada de datos en tus aplicaciones Flutter.

Curso de Desarrollo con Flutter

Módulo 1: Introducción a Flutter

Módulo 2: Conceptos Básicos de Programación en Dart

Módulo 3: Widgets en Flutter

Módulo 4: Gestión de Estado

Módulo 5: Navegación y Enrutamiento

Módulo 6: Redes y APIs

Módulo 7: Persistencia y Almacenamiento

Módulo 8: Conceptos Avanzados de Flutter

Módulo 9: Pruebas y Depuración

Módulo 10: Despliegue y Mantenimiento

Módulo 11: Flutter para Web y Escritorio

© Copyright 2024. Todos los derechos reservados