Flutter in mobiele ontwikkeling: wat het is, kernconcepten en hoe het werkt

Auteur: IT Sectr Gepubliceerd: 2026-07-09 Leestijd: 11 min

Flutter is een UI-framework van Google voor native cross-platform applicaties. Volgens Flutter Docs (2025) wordt Flutter gebruikt in meer dan 500.000 apps in Google Play. Het begrijpen van Widget, StatefulWidget, BuildContext en de renderboom is de basis van Flutter-ontwikkeling.

Belangrijkste punten

  • Widget — basis bouwsteen. StatelessWidget (onveranderlijk) vs StatefulWidget (veranderlijk met setState()).
  • Drie bomen: Widget Tree (configuratie), Element Tree (elementen), RenderObject Tree (rendering).
  • BuildContext — toegang tot InheritedWidget: Theme, MediaQuery, Navigator. InheritedWidget — gegevens doorgeven naar beneden.
  • Navigator — schermstack (Routes). Navigator 2.0 (Router) — declaratieve navigatie.
  • Hot Reload — wijzigingen injecteren in 1-2 seconden. Behoudt status. Hot Restart — volledige herstart.

Flutter: basis van Widget, StatelessWidget en StatefulWidget

Widget — een declaratieve beschrijving van een deel van de UI. Alles in Flutter is een Widget: van een knop tot de app zelf. Een Widget is configuratie (niet de UI zelf). StatelessWidget — een onveranderlijke Widget. build() wordt eenmalig aangeroepen. Heeft geen status. Gebruikt voor statische inhoud. StatefulWidget — een veranderlijke Widget. Heeft een State-object dat kan veranderen. setState() — triggert herbouw. State — een veranderlijk object gekoppeld aan een StatefulWidget. Bevat gegevens die kunnen veranderen.

StatelessWidget vs StatefulWidget

StatelessWidget — build() wordt eenmalig aangeroepen. Geschikt voor koppen, pictogrammen, statische teksten. StatefulWidget — build() wordt elke keer aangeroepen wanneer setState() wordt aangeroepen. Geschikt voor formulieren, lijsten met wijzigingen, timers. InheritedWidget — gegevens doorgeven naar beneden zonder expliciete overdracht via constructors. Theme, MediaQuery, Navigator — InheritedWidgets. BuildContext — positie van een Widget in de boom. context.of<T>, context.watch<T>, context.select<T,R> — toegang tot InheritedWidget.

dart
// Voorbeeld Flutter Widget: StatefulWidget met setState
class CounterWidget extends StatefulWidget {
  const CounterWidget({Key? key}) : super(key: key);

  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

  void _increment() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter Counter')),
      body: const Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('You have pushed the button:'),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _increment,
        child: const Icon(Icons.add),
      ),
    );
  }
}

Widget — configuratie. StatelessWidget — onveranderlijk. StatefulWidget — veranderlijk met setState(). IT Sectr raadt aan om met StatelessWidget te beginnen en over te stappen naar StatefulWidget alleen wanneer status nodig is.

Bomen (Widget Tree, Element Tree, RenderObject Tree)

Flutter gebruikt drie bomen voor efficiënte weergave. Widget Tree — configuratieboom. Widgets worden vaak gemaakt (elke build), lichtgewicht. Element Tree — elementenboom. Eén element per Widget (als het type niet verandert). Element — brug tussen Widget en RenderObject. RenderObject Tree — weergaveboom. Behandelt afmetingen, posities, tekenen. RenderObject — zwaar, zelden gemaakt. Flutter vergelijkt de Widget Tree en werkt de Element Tree bij, wat de RenderObject Tree-update activeert.

Keys en Element Tree

Key — Widget-identificatie in de Element Tree. ValueKey, ObjectKey, UniqueKey, PageStorageKey. Keys stellen Flutter in staat oude en nieuwe Widgets te matchen tijdens herbouw. Zonder Keys matcht Flutter op Widget-type en positie. GlobalKey — toegang tot State vanuit een andere Widget. Gebruikt voor: complexe formulieren, animaties, toegang tot State in tests. IT Sectr raadt aan Keys te gebruiken voor lijsten (List.generate) en GlobalKey te vermijden tenzij nodig.

Expanded — Widget die beschikbare ruimte vult in Row/Column/Flex. Flexible — dwingt vulling niet af (kan kleiner zijn). MediaQuery — InheritedWidget met apparaatinformatie: schermgrootte, oriëntatie, platform, tekstschaalfactor. Theme/ThemeData — gecentraliseerd thema. Theme.of(context) — toegang. MaterialApp — root Widget voor configuratie van routing, thema's, locaties. Scaffold — basislay-out met AppBar, Drawer, BottomNavigationBar. AppBar — bovenpaneel.

Navigator — routestack (Routes). Navigator.push — scherm openen (retourneert Future). Navigator.pop — sluiten (met resultaat). MaterialPageRoute — geanimeerde overgang (schuif van rechts). Named Routes — string-identificaties. onGenerateRoute — gecentraliseerde handler. Navigator 2.0 (Router + RouteInformationParser + RouterDelegate) — declaratieve navigatie voor web, deep linking en complexe scenario's.

Navigator 2.0 — declaratieve navigatie. Router — centraal Widget. RouteInformationParser — URL-parsing. RouterDelegate — stackbeheer. GoRouter (pakket) — vereenvoudigde wrapper over Navigator 2.0. Ondersteunt: benoemde routes, parameters, redirect, deep linking. IT Sectr raadt GoRouter aan voor de meeste projecten en Navigator 2.0 alleen voor complexe scenario's (web, desktop).

Asynchroon (FutureBuilder, StreamBuilder)

FutureBuilder — Widget dat UI bouwt op basis van een Future. connectionState: none, waiting, active, done. Gebruikt voor: HTTP-verzoeken, DB-lezingen, timers. StreamBuilder — Widget voor Stream (oneindige gegevensstroom). snapshot.data, snapshot.hasError, snapshot.hasData. Gebruikt voor: WebSocket, Firebase, locatie-updates. Beide Widgets herbouwen bij ontvangst van nieuwe gegevens.

Statusbeheer

Provider — eenvoudige DI + statusbeheer. ChangeNotifierProvider, MultiProvider. Riverpod — moderne vervanging voor Provider: compile-veilig, onafhankelijk van BuildContext. Bloc — Event-Driven architectuur: Cubit (eenvoudige gebeurtenissen) vs Bloc (complexe). GetX — lichtgewicht statusbeheer + DI + routing. setState — eenvoudigst, voor lokale status. IT Sectr raadt Riverpod aan voor nieuwe projecten en Provider voor bestaande.

Thema's en aanpassing (MediaQuery, ThemeData)

MediaQuery — schermgrootte, oriëntatie, platform, textScaleFactor. MediaQuery.of(context).size.width. ThemeData — app-thema: kleuren, lettertypen, vormen. Theme.of(context).textTheme.bodyLarge. Hot Reload — code-injectie in een draaiende app. Behoudt status. Ondersteunt niet: wijzigen van main(), globale variabelen, statische velden. Hot Restart — volledige app-herstart (statusverlies). Hot Reload — het belangrijkste voordeel van Flutter voor ontwikkelaars.

Widget-type Beschrijving Voorbeelden
StatelessWidgetOnveranderlijk, eenmalig buildText, Icon, Padding, Center
StatefulWidgetVeranderlijk, setState herbouwTextField, Checkbox, AnimationController
InheritedWidgetGegevens doorgeven naar benedenTheme, MediaQuery, Navigator
ProxyWidgetWrapper voor andere WidgetsParentDataWidget (Positioned, Expanded)
RenderObjectWidgetMaakt RenderObjectColumn, Row, Stack (aangepast)

StatelessWidget — voor statische inhoud. StatefulWidget — voor dynamische inhoud. InheritedWidget — voor DI. IT Sectr raadt standaard StatelessWidget aan en StatefulWidget alleen wanneer nodig.

Responsieve lay-out

LayoutBuilder — aanpassen aan afmetingen van ouder. OrientationBuilder — aanpassen aan oriëntatie. Expanded vs Flexible — ruimteverdeling in Row/Column. MediaQuery — breekpunten voor tablets en desktops. SafeArea — marges van systeemelementen (inkeping, statusbalk). AspectRatio — verhoudingen behouden. IT Sectr raadt LayoutBuilder aan voor adaptieve lay-outs en OrientationBuilder voor liggende oriëntatie.

Testen (Widget, Integration, Unit)

Unit tests — testen van bedrijfslogica, repositories, modellen. dart test — uitvoeren. Widget tests — testen van widgets in isolatie. WidgetTester — pumpWidget, tap, enterText. Integratietests — volledige scenario's op een echt apparaat/emulator. Mockito — mocken van afhankelijkheden. Golden tests — schermafbeeldingvergelijking (golden bestanden). IT Sectr raadt Widget tests aan voor elk scherm en Unit tests voor bedrijfslogica.

dart
void main() {
  testWidgets('Counter increments on tap', (tester) async {
    await tester.pumpWidget(const MaterialApp(home: CounterWidget()));

    expect(find.text('0'), findsOneWidget);

    await tester.tap(find.byType(FloatingActionButton));
    await tester.pump();

    expect(find.text('1'), findsOneWidget);
  });
}

Animaties (Impliciet, Expliciet, Hero)

Impliciete animaties — AnimatedContainer, AnimatedOpacity, AnimatedPadding, TweenAnimationBuilder. Eigenschapswijzigingen worden automatisch geanimeerd. Expliciete animaties — AnimationController met Tween. forward() / reverse(). Hero-animatie — Hero Widget met een tag — overgangsanimatie tussen schermen. Gespreide animatie — animatieketen met Interval. Lottie — integratie van After Effects-animaties. Rive — interactieve animaties (state machine). IT Sectr raadt AnimatedContainer aan voor 80% van de gevallen en AnimationController voor complexe scenario's.

dart
class AnimatedBox extends StatefulWidget {
  @override
  State<AnimatedBox> createState() => _AnimatedBoxState();
}

class _AnimatedBoxState extends State<AnimatedBox> {
  bool _expanded = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => setState(() => _expanded = !_expanded),
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 300),
        curve: Curves.easeInOut,
        width: _expanded ? 200 : 100,
        height: _expanded ? 200 : 100,
        color: _expanded ? Colors.blue : Colors.red,
        child: const Center(child: Text('Tap me')),
      ),
    );
  }
}

Netwerk (http, dio, graphql)

http — eenvoudige HTTP-client (get, post, put, delete). dio — geavanceerde client met interceptors, timeouts, herhalingen, logging. graphql_flutter — GraphQL-client voor Flutter. json_serializable — genereren van fromJson/toJson via annotaties. Retrofit Dart — type-safe HTTP-client zoals Retrofit. WebSocket — via web_socket_channel. Firebase — Cloud Firestore, Realtime Database, Cloud Functions. IT Sectr raadt dio aan voor REST API en graphql_flutter voor GraphQL.

Flutter DevTools — gereedschapsset: Inspector (widgetboom), Timeline (prestaties), Memory, Network, Logging. Profile mode — profileren zonder debug. Performance overlay — FPS, bouwtijden. Flame chart — vlamgrafiek tracing. DevTools — essentieel hulpmiddel voor het optimaliseren van Flutter-applicaties in productie.

Flutter Web — compilatie van Flutter naar WASM (WebAssembly). CanvasKit (Skia) vs HTML renderer. CanvasKit — pixel-perfect, maar zwaarder. HTML renderer — licht, maar met beperkingen. WASM (Flutter 3.22+) — native prestaties. Responsieve aanpassing via LayoutBuilder en MediaQuery. IT Sectr raadt CanvasKit aan voor desktop webapplicaties en HTML renderer voor contentsites.

Veelgestelde vragen

Wat is het verschil tussen StatelessWidget en StatefulWidget?

StatelessWidget — onveranderlijk, eenmalig build. StatefulWidget — met veranderlijke State en setState().

Wat zijn Widget Tree, Element Tree en RenderObject Tree?

Widget Tree — configuratie. Element Tree — brug. RenderObject Tree — weergave (afmetingen, tekenen).

Wat zijn BuildContext en InheritedWidget?

BuildContext — Widget-positie in de boom. InheritedWidget — gegevens doorgeven naar beneden (Theme, MediaQuery).

Hoe werken Navigator en Route in Flutter?

Navigator — schermstack. push() → pop(). Named Routes — stringnamen. Navigator 2.0 — declaratief.

Hoe werkt Hot Reload in Flutter?

Hot Reload — code-injectie in 1-2 seconden, statusbehoud. Hot Restart — volledige herstart.

Samenvatting

  • Widget — alles is een Widget. StatelessWidget vs StatefulWidget — basisdichotomie.
  • Drie bomen: Widget → Element → RenderObject. Widget — configuratie, RenderObject — weergave.
  • BuildContext + InheritedWidget — toegang tot Theme, MediaQuery, Navigator zonder expliciete overdracht.
  • Navigator — schermstack. Navigator 2.0 — declaratieve navigatie voor web en deep links.
  • FutureBuilder — voor Future. StreamBuilder — voor Stream (Firebase, WebSocket).
  • MaterialApp + Scaffold — app-skelet. ThemeData — gecentraliseerd thema.
  • Hot Reload — Flutter's killer feature. Code-update in seconden met statusbehoud.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project