Input e Formulários
TextField
Campo de texto para entrada do usuário:
TextField(
decoration: InputDecoration(
labelText: 'Nome',
hintText: 'Digite seu nome',
border: OutlineInputBorder(),
),
onChanged: (value) {
print('Valor digitado: $value');
},
)
Com controller:
class MeuFormulario extends StatefulWidget {
State<MeuFormulario> createState() => _MeuFormularioState();
}
class _MeuFormularioState extends State<MeuFormulario> {
final _controller = TextEditingController();
void dispose() {
_controller.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return TextField(
controller: _controller,
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
);
}
}
Form
Form agrupa e valida múltiplos campos:
class FormularioCompleto extends StatefulWidget {
State<FormularioCompleto> createState() => _FormularioCompletoState();
}
class _FormularioCompletoState extends State<FormularioCompleto> {
final _formKey = GlobalKey<FormState>();
final _nomeController = TextEditingController();
final _emailController = TextEditingController();
void dispose() {
_nomeController.dispose();
_emailController.dispose();
super.dispose();
}
void _enviar() {
if (_formKey.currentState!.validate()) {
print('Nome: ${_nomeController.text}');
print('Email: ${_emailController.text}');
}
}
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _nomeController,
decoration: InputDecoration(labelText: 'Nome'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Por favor, digite seu nome';
}
return null;
},
),
TextFormField(
controller: _emailController,
decoration: InputDecoration(labelText: 'Email'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Por favor, digite seu email';
}
if (!value.contains('@')) {
return 'Email inválido';
}
return null;
},
),
ElevatedButton(
onPressed: _enviar,
child: Text('Enviar'),
),
],
),
);
}
}
Validação
Validação pode ser feita de várias formas:
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Campo obrigatório';
}
if (value.length < 3) {
return 'Mínimo de 3 caracteres';
}
return null; // null significa que a validação passou
},
)
Exercícios
-
TextField básico: Crie um
TextFieldsimples com um label e um hint. Exiba o valor digitado em umTextabaixo do campo. -
TextEditingController: Crie um formulário com dois campos (nome e email) usando
TextEditingController. Adicione um botão que limpe ambos os campos quando pressionado. -
Form com validação: Crie um
Formcom dois campos: nome (obrigatório, mínimo 3 caracteres) e email (obrigatório, deve conter @). Exiba mensagens de erro quando a validação falhar. -
Validação customizada: Crie um campo de senha com validação que verifique se a senha tem pelo menos 8 caracteres e contém pelo menos um número.
-
Formulário completo: Crie um formulário completo com nome, email, telefone e mensagem. Todos os campos devem ser validados e o formulário só deve ser submetido se todos estiverem válidos.
Soluções
Ver solução do exercício 1
import 'package:flutter/material.dart';
class CampoTexto extends StatefulWidget {
State<CampoTexto> createState() => _CampoTextoState();
}
class _CampoTextoState extends State<CampoTexto> {
String _texto = '';
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('TextField')),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
TextField(
decoration: InputDecoration(
labelText: 'Digite algo',
hintText: 'Ex: Olá, Flutter!',
border: OutlineInputBorder(),
),
onChanged: (value) {
setState(() {
_texto = value;
});
},
),
SizedBox(height: 20),
Text('Valor: $_texto'),
],
),
),
);
}
}
void main() {
runApp(MaterialApp(home: CampoTexto()));
}
Ver solução do exercício 2
import 'package:flutter/material.dart';
class FormularioController extends StatefulWidget {
State<FormularioController> createState() => _FormularioControllerState();
}
class _FormularioControllerState extends State<FormularioController> {
final _nomeController = TextEditingController();
final _emailController = TextEditingController();
void dispose() {
_nomeController.dispose();
_emailController.dispose();
super.dispose();
}
void _limpar() {
_nomeController.clear();
_emailController.clear();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Formulário')),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
TextField(
controller: _nomeController,
decoration: InputDecoration(
labelText: 'Nome',
border: OutlineInputBorder(),
),
),
SizedBox(height: 16),
TextField(
controller: _emailController,
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _limpar,
child: Text('Limpar'),
),
],
),
),
);
}
}
void main() {
runApp(MaterialApp(home: FormularioController()));
}
Ver solução do exercício 3
import 'package:flutter/material.dart';
class FormValidacao extends StatefulWidget {
State<FormValidacao> createState() => _FormValidacaoState();
}
class _FormValidacaoState extends State<FormValidacao> {
final _formKey = GlobalKey<FormState>();
void _enviar() {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Formulário válido!')),
);
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Validação')),
body: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
labelText: 'Nome',
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Nome é obrigatório';
}
if (value.length < 3) {
return 'Nome deve ter pelo menos 3 caracteres';
}
return null;
},
),
SizedBox(height: 16),
TextFormField(
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email é obrigatório';
}
if (!value.contains('@')) {
return 'Email inválido';
}
return null;
},
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _enviar,
child: Text('Enviar'),
),
],
),
),
),
);
}
}
void main() {
runApp(MaterialApp(home: FormValidacao()));
}
Ver solução do exercício 4
import 'package:flutter/material.dart';
class SenhaValidacao extends StatefulWidget {
State<SenhaValidacao> createState() => _SenhaValidacaoState();
}
class _SenhaValidacaoState extends State<SenhaValidacao> {
final _formKey = GlobalKey<FormState>();
bool _validarSenha(String? senha) {
if (senha == null || senha.isEmpty) {
return false;
}
if (senha.length < 8) {
return false;
}
if (!senha.contains(RegExp(r'[0-9]'))) {
return false;
}
return true;
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Validação de Senha')),
body: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
obscureText: true,
decoration: InputDecoration(
labelText: 'Senha',
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Senha é obrigatória';
}
if (value.length < 8) {
return 'Senha deve ter pelo menos 8 caracteres';
}
if (!value.contains(RegExp(r'[0-9]'))) {
return 'Senha deve conter pelo menos um número';
}
return null;
},
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Senha válida!')),
);
}
},
child: Text('Validar'),
),
],
),
),
),
);
}
}
void main() {
runApp(MaterialApp(home: SenhaValidacao()));
}
Ver solução do exercício 5
import 'package:flutter/material.dart';
class FormularioCompleto extends StatefulWidget {
State<FormularioCompleto> createState() => _FormularioCompletoState();
}
class _FormularioCompletoState extends State<FormularioCompleto> {
final _formKey = GlobalKey<FormState>();
void _enviar() {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Formulário enviado com sucesso!')),
);
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Formulário Completo')),
body: SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
labelText: 'Nome',
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Nome é obrigatório';
}
return null;
},
),
SizedBox(height: 16),
TextFormField(
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email é obrigatório';
}
if (!value.contains('@')) {
return 'Email inválido';
}
return null;
},
),
SizedBox(height: 16),
TextFormField(
decoration: InputDecoration(
labelText: 'Telefone',
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Telefone é obrigatório';
}
return null;
},
),
SizedBox(height: 16),
TextFormField(
maxLines: 4,
decoration: InputDecoration(
labelText: 'Mensagem',
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Mensagem é obrigatória';
}
return null;
},
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _enviar,
child: Text('Enviar'),
),
],
),
),
),
);
}
}
void main() {
runApp(MaterialApp(home: FormularioCompleto()));
}