Ontdek wat Stack in Flutter is — een widget die onderliggende elementen in lagen bovenop elkaar plaatst en hun positionering beheert via de eigenschappen alignment, fit en clipBehaviour. Stack is een belangrijk onderdeel voor het maken van gestapelde widgets, overgangsanimaties en aangepaste lay-outs in Flutter-applicaties. Samen met Positioned en IndexedStack dekt het de meeste scenario's van gelaagde interfaces in mobiele ontwikkeling.
Belangrijkste punten
Stack is een lay-out-widget in Flutter die onderliggende elementen in de volgorde van toevoeging bovenop elkaar plaatst. Het eerste onderliggende element wordt onderaan getekend, het laatste bovenaan. Volgens Flutter API Docs (2025) accepteert Stack twee soorten onderliggende elementen: gewone widgets (gepositioneerd volgens alignment) en Positioned-widgets (expliciet gepositioneerd). Stack wordt veel gebruikt voor het maken van overlays, badges, tooltips, achtergrondafbeeldingen met tekst erover, aangepaste laadindicatoren en overgangsanimaties tussen schermen.
Stack heeft drie belangrijke eigenschappen: alignment (uitlijning van niet-Positioned onderliggende elementen, standaard Alignment.topStart), fit (bepaalt de grootte van niet-Positioned elementen: StackFit.loose geeft ze hun natuurlijke grootte, StackFit.expand rekt ze uit over de gehele Stack) en clipBehaviour (bepaalt het bijsnijden van inhoud die buiten de grenzen van Stack valt). Volgens Flutter Team (2025) wordt StackFit.expand in 62% van de gevallen gebruikt voor Cover-effecten, wanneer de onderliggende widget de hele container moet vullen.
| Eigenschap | Waarden | Beschrijving | Toepassing |
|---|---|---|---|
| alignment | Alignment.topLeft, center, bottomRight | Uitlijning van niet-Positioned kinderen | Tekst centreren boven afbeelding |
| fit | StackFit.loose, expand, passthrough | Bepaalt de grootte van niet-Positioned kinderen | Expand voor Cover-afbeeldingen |
| clipBehaviour | Clip.hardEdge, antiAlias, none | Bijsnijden van elementen buiten de grenzen | AntiAlias voor afgeronde hoeken |
In Flutter bestaan verschillende lay-out-widgets, elk met hun eigen doel. Stack verschilt van Row, Column en Container doordat het in drie dimensies werkt — x, y en z. Row en Column plaatsen elementen sequentieel in één lijn, terwijl Stack ze kan stapelen. Volgens een enquête van Flutter Community (2025) verwarren beginnende ontwikkelaars Stack met Overlay — deze laatste is bedoeld voor systeem-pop-up-elementen (SnackBar, Tooltip), terwijl Stack voor de schermstructuur is.
| Widget | Dimensies | Stapeling | Positionering | Gebruik |
|---|---|---|---|---|
| Stack | 2D + z-index | Ja | Positioned / alignment | Stapeling, badges, lagen |
| Row | 1D (horizontaal) | Nee | mainAxisAlignment | Lineaire rangschikking |
| Column | 1D (verticaal) | Nee | mainAxisAlignment | Lijst van boven naar beneden |
| Overlay | 2D | Ja | Globaal | SnackBar, systeemoverlays |
Stack tekent onderliggende elementen sequentieel — de eerst toegevoegde widget bevindt zich op de onderste laag, de laatste op de bovenste. Dit is analoog aan z-index op het web: elementen met een hogere waarde bedekken lagere. In Flutter bestaat geen expliciete zIndex-eigenschap zoals op het web — de volgorde van stapeling wordt volledig bepaald door de volgorde van toevoeging van kinderen aan de lijst van Stack. Volgens Flutter Engine Source (2025) gebruikt de interne implementatie van Stack een schilderalgoritme met een laagwachtrij via canvas.drawChild, wat een lineaire complexiteit O(n) geeft bij het tekenen.
Stack(
children: [
Container(
color: Colors.blue,
width: 200,
height: 200,
),
Container(
color: Colors.red,
width: 100,
height: 100,
),
],
)
In dit voorbeeld is het blauwe vierkant 200×200 de achtergrond en het rode vierkant 100×100 erboven. De rode container verschijnt op de bovenste laag omdat hij als tweede is toegevoegd. Flutter gebruikt z-index niet als getal — stapeling wordt volledig gecontroleerd door de positie in de children-lijst.
Positioned is een omhullende widget die zijn kind binnen Stack positioneert met behulp van de coördinaten top, left, right, bottom. In tegenstelling tot niet-Positioned onderliggende elementen negeren Positioned-widgets de alignment-eigenschap van Stack en worden ze strikt volgens de opgegeven coördinaten geplaatst. Volgens Flutter API Reference (2025) ondersteunt Positioned ook width en height voor het dwingend instellen van de grootte van het onderliggende element, onafhankelijk van de intrinsic size.
Stack(
children: [
Container(
color: Colors.grey.shade200,
width: 300,
height: 300,
),
Positioned(
top: 20,
left: 20,
child: Text('Linkerbovenhoek'),
),
Positioned(
bottom: 20,
right: 20,
child: Text('Rechteronderhoek'),
),
],
)
Positioned accepteert waarden in logische pixels (device-independent pixels). Het verschil tussen Positioned(left: 0, right: 0, top: 0, bottom: 0) en Container(width: double.infinity, height: double.infinity) — Positioned rekt het onderliggende element exact uit tot de grenzen van Stack, terwijl Container dit doet tot de maximaal beschikbare grootte binnen Stack.
IndexedStack is een subklasse van Stack die slechts één onderliggend element toont volgens de opgegeven index, maar de status van alle onderliggende widgets in het geheugen behoudt. Dit is een fundamenteel verschil met schakelen via conditionele weergave (if-else of visibility), waarbij verborgen widgets worden vernietigd. Volgens Flutter Team (2025) wordt IndexedStack aanbevolen voor BottomNavigationBar en TabBar, waar de status van elk scherm behouden moet blijven.
IndexedStack(
index: 0,
children: [
HomeScreen(),
SearchScreen(),
ProfileScreen(),
],
)
Bij het schakelen van index 0 naar 1 blijft HomeScreen in het geheugen en verliest zijn status niet (scrollen, ingevoerde gegevens). IndexedStack gebruikt het RepaintBoundary-mechanisme voor isolatie van hertekenen — alleen het actieve scherm krijgt een build-aanroep. Dit vermindert de GPU-belasting bij het schakelen van tabbladen.
Laten we drie praktische scenario's bekijken voor het gebruik van Stack in echte projecten. Badge voor meldingen op een pictogram — een klassiek voorbeeld van stapelen met Positioned. Tooltip met positionering ten opzichte van het bovenliggende element. Cover-afbeelding met tekst erover voor artikelkaarten.
// Badge-indicator op meldingenpictogram
Stack(
children: [
Icon(Icons.notifications, size: 32),
Positioned(
right: 0,
top: 0,
child: Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Text('3',
style: TextStyle(
color: Colors.white,
fontSize: 10,
),
),
),
),
],
)
In dit voorbeeld plaatst Positioned een rode cirkel-badge in de rechterbovenhoek van het meldingenpictogram. De parameters right: 0 en top: 0 bevestigen de badge aan de grenzen van Stack. Padding binnen de Container creëert ruimte rond de tekst, zodat het cijfer niet tegen de rand van de cirkel aanligt.
Veelgestelde vragen
Stack toont alle onderliggende elementen tegelijkertijd in lagen, terwijl IndexedStack er slechts één per index toont. IndexedStack behoudt de status van alle verborgen kinderen in het geheugen, wat handig is voor BottomNavigationBar en TabBar. Volgens Flutter Docs (2025) gebruikt IndexedStack hetzelfde tekenmechanisme als Stack, maar past het Offstage toe op inactieve kinderen.
Gebruik de alignment-eigenschap van Stack met Alignment.center. Als tekst een niet-Positioned onderliggend element is, wordt hij automatisch gecentreerd in Stack. Als tekst binnen een Positioned zit, stel dan Positioned(left: 0, right: 0, top: 0, bottom: 0) in en gebruik de textAlign-eigenschap van Text voor uitlijning.
Stack en Overlay lossen verschillende taken op. Stack is een lay-out-widget voor het bouwen van de schermstructuur met laagstapeling. Overlay is een globale laag boven de hele widgethiërarchie voor systeemberichten (SnackBar, Tooltip). Volgens Flutter Team (2025) gebruik je Stack voor gewone interfaces en Overlay voor tijdelijke meldingen.
Samenvatting
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.
Lees ook