Form-widget en controllers
Leer de widget `Form` te gebruiken voor het beheren van meerdere tekstvelden en gebruikersinvoer te besturen met `TextEditingController`.
Form-widget en controllers is een gratis Mobiele ontwikkeling met Flutter-les op CoddyKit. Dit is les 1 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Mobiele ontwikkeling met Flutter. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Mobiele ontwikkeling met Flutter bevat in totaal 4 lessen.
Formulieren: de basis van gebruikersinvoer
Formulieren zijn essentieel voor vrijwel elke interactieve mobiele applicatie. Hiermee kunnen gebruikers gegevens invoeren, bijvoorbeeld om in te loggen, zich te registreren, profielen bij te werken of informatie in te dienen.
In Flutter worden formulieren opgebouwd met een combinatie van widgets die zijn ontworpen om gebruikersinvoer efficiënt en betrouwbaar te verwerken.
Invoer organiseren met Form
De widget Form fungeert als container voor het groeperen van meerdere invoervelden. Deze biedt een manier om de status van deze velden te beheren, ze te valideren en hun waarden in één keer op te slaan.
Je kunt deze zien als de ouder die toezicht houdt op al zijn invoerkinderen. Zo begin je met een eenvoudige formulierstructuur:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('My Form App')),
body: Center(
child: Form(
child: Column(
children: [
// Form fields will go here
],
),
),
),
),
);
}
}Je eerste invoer: TextFormField
Hoewel je TextField voor invoer kunt gebruiken, is TextFormField speciaal ontworpen om naadloos binnen een Form-widget te werken. Deze biedt ingebouwde functies voor validatie, opslaan en het weergeven van fouten.
Laten we een eenvoudig TextFormField aan ons formulier toevoegen:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('My Form App')),
body: Center(
child: Form(
child: Column(
children: const [
Padding(
padding: EdgeInsets.all(16.0),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Enter your name',
border: OutlineInputBorder(),
),
),
),
],
),
),
),
),
);
}
}Invoer beheren: TextEditingController
Om de tekst in een TextFormField (of TextField) programmatisch te lezen, in te stellen of te wijzigen, gebruik je een TextEditingController. Deze vormt een communicatiebrug tussen je code en de tekstinvoerwidget.
Het is cruciaal om controllers op te ruimen met dispose wanneer je ze niet meer nodig hebt, om geheugenlekken te voorkomen. Dit doe je meestal in de methode dispose() van een StatefulWidget.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final TextEditingController _myController = TextEditingController();
@override
void dispose() {
_myController.dispose(); // Important: dispose the controller!
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Controller Demo')),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: TextField( // Using TextField for clarity
controller: _myController,
decoration: const InputDecoration(
labelText: 'Type something',
border: OutlineInputBorder(),
),
),
),
),
),
);
}
}Controller en TextFormField koppelen
Laten we nu onze TextEditingController koppelen aan een TextFormField. Zo kunnen we de tekst die de gebruiker invoert rechtstreeks vanuit de controller benaderen, bijvoorbeeld wanneer er op een knop wordt gedrukt.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final TextEditingController _nameController = TextEditingController();
@override
void dispose() {
_nameController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Controller Link')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
controller: _nameController,
decoration: const InputDecoration(
labelText: 'Your Name',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: () {
print('Name: ${_nameController.text}');
},
child: const Text('Get Name'),
),
],
),
),
),
);
}
}Formulierstatus beheren met GlobalKey
Als je wilt werken met de Form-widget zelf – bijvoorbeeld om alle velden te valideren of hun status op te slaan – heb je een manier nodig om ernaar te verwijzen. Dit doe je met een GlobalKey<FormState>.
De GlobalKey geeft toegang tot de interne status van de Form, zodat je acties zoals validate() of save() op alle onderliggende widgets kunt uitvoeren.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _formKey = GlobalKey<FormState>(); // Declare the GlobalKey
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('GlobalKey Demo')),
body: Form(
key: _formKey, // Assign the GlobalKey to the Form
child: Column(
children: const [
Padding(
padding: EdgeInsets.all(16.0),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
),
),
],
),
),
),
);
}
}Je formulier verzenden
Met een combinatie van Form, GlobalKey en TextEditingControllers kun je een functioneel formulier bouwen. Wanneer er op een verzendknop wordt gedrukt, kun je met _formKey toegang krijgen tot de status van het formulier en de invoer verwerken.
Hier zie je een voorbeeld van een loginformulier waarin we de verzamelde gegevens bij het verzenden afdrukken.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _usernameController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
@override
void dispose() {
_usernameController.dispose();
_passwordController.dispose();
super.dispose();
}
void _submitForm() {
// In a real app, you'd add validation here (covered in next lesson)
print('Username: ${_usernameController.text}');
print('Password: ${_passwordController.text}');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Login Data')),
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Login Form')),
body: Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
controller: _usernameController,
decoration: const InputDecoration(labelText: 'Username'),
),
TextFormField(
controller: _passwordController,
obscureText: true,
decoration: const InputDecoration(labelText: 'Password'),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: ElevatedButton(
onPressed: _submitForm,
child: const Text('Submit'),
),
),
],
),
),
),
),
);
}
}Alle formulierinvoer ophalen
Wanneer je meerdere TextFormField-widgets in je formulier hebt en elk veld aan een eigen TextEditingController is gekoppeld, kun je alle gebruikersinvoer eenvoudig ophalen. Je leest daarvoor de eigenschap .text van elke controller uit.
Zo kun je alle benodigde gegevens eenvoudig verzamelen wanneer de gebruiker klaar is om de informatie te verzenden.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final TextEditingController _emailController = TextEditingController();
final TextEditingController _phoneController = TextEditingController();
@override
void dispose() {
_emailController.dispose();
_phoneController.dispose();
super.dispose();
}
void _getData() {
print('Email: ${_emailController.text}');
print('Phone: ${_phoneController.text}');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Email: ${_emailController.text}, Phone: ${_phoneController.text}')),
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Multi-Input Get')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
controller: _emailController,
decoration: const InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
),
const SizedBox(height: 10),
TextFormField(
controller: _phoneController,
decoration: const InputDecoration(labelText: 'Phone'),
keyboardType: TextInputType.phone,
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _getData,
child: const Text('Show Data'),
),
],
),
),
),
);
}
}Invoervelden resetten
Na het verzenden van een formulier, of als je een knop 'Wissen' wilt aanbieden, kun je de tekst in een TextFormField eenvoudig resetten. Roep daarvoor de .clear()-methode aan op de bijbehorende TextEditingController, of stel de eigenschap .text in op een lege tekenreeks.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final TextEditingController _inputController = TextEditingController();
@override
void dispose() {
_inputController.dispose();
super.dispose();
}
void _clearInput() {
_inputController.clear(); // Clears the text in the TextFormField
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Clear Input Demo')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
controller: _inputController,
decoration: const InputDecoration(
labelText: 'Type here',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: _clearInput,
child: const Text('Clear Text'),
),
],
),
),
),
);
}
}Controle van formulier en controller
Test je begrip van Flutter-formulieren en controllers.
Samenvatting: formulieren en controllers
In deze les hebben we de belangrijkste elementen verkend voor het bouwen van formulieren voor gebruikersinvoer in Flutter:
- De
Form-widget fungeert als bovenliggende container voor het beheren van meerdere invoervelden. TextFormFieldis de gespecialiseerde widget voor tekstinvoer binnen eenFormen biedt ingebouwde integratie met formulieren.- Met
TextEditingControllerkun je de tekst in een invoerveld programmatisch beheren, lezen en aanpassen. - Een
GlobalKey<FormState>wordt gebruikt om toegang te krijgen tot de status van deForm, zodat je acties zoals valideren of opslaan kunt uitvoeren. - Vergeet niet om je
TextEditingControllers met dispose op te ruimen om geheugenlekken te voorkomen!
Vervolgens gaan we dieper in op technieken voor invoervalidatie, zodat je formulieren correcte en bruikbare gegevens verzamelen!
Leer Dart met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 22
- Lessen
- 88
Veelgestelde vragen
Is de les “Form-widget en controllers” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad Mobiele ontwikkeling met Flutter, waaronder “Form-widget en controllers”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Mobiele ontwikkeling met Flutter bevat in totaal 4 lessen.
Wat leer ik in “Form-widget en controllers”?
Leer de widget `Form` te gebruiken voor het beheren van meerdere tekstvelden en gebruikersinvoer te besturen met `TextEditingController`. Je oefent met Mobiele ontwikkeling met Flutter door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Mobiele ontwikkeling met Flutter te beginnen?
Ervaring vooraf is niet nodig. Mobiele ontwikkeling met Flutter op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “Form-widget en controllers”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Mobiele ontwikkeling met Flutter?
Ja. Elke les over Mobiele ontwikkeling met Flutter bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Form-widget en controllers
- Technieken voor invoervalidatie
- Aangepaste formuliervelden
- Focus, toetsenbord en input-UX