Lär dig vad Stack är i Flutter — en widget som placerar underordnade element ovanpå varandra i form av lager och styr deras positionering via egenskaperna alignment, fit och clipBehaviour. Stack är en nyckelkomponent för att skapa stapling av widgets, övergångsanimationer och anpassade layouter i Flutter-applikationer. Tillsammans med Positioned och IndexedStack täcker det de flesta scenarier för lagerbaserade gränssnitt inom mobilutveckling.
Huvudpunkter
Stack är en layout-widget i Flutter som placerar underordnade element ovanpå varandra i den ordning de läggs till. Det första underordnade elementet ritas längst ner, det sista längst upp. Enligt Flutter API Docs (2025) accepterar Stack två typer av underordnade element: vanliga widgets (positionerade enligt alignment) och Positioned-widgets (explicit positionerade). Stack används i stor utsträckning för att skapa överlägg, märken, tooltips, bakgrundsbilder med text över, anpassade laddningsindikatorer och övergångsanimationer mellan skärmar.
Stack har tre viktiga egenskaper: alignment (justering av icke-Positioned underordnade element, som standard Alignment.topStart), fit (bestämmer storleken på icke-Positioned element: StackFit.loose ger dem naturlig storlek, StackFit.expand sträcker ut dem över hela Stack) och clipBehaviour (bestämmer beskärning av innehåll som går utanför Stack:s gränser). Enligt Flutter Team (2025) används StackFit.expand i 62% av fallen för Cover-effekter, när den underordnade widgeten måste fylla hela containern.
| Egenskap | Värden | Beskrivning | Användning |
|---|---|---|---|
| alignment | Alignment.topLeft, center, bottomRight | Justering av icke-Positioned barn | Centrera text ovanför bild |
| fit | StackFit.loose, expand, passthrough | Bestämmer storlek på icke-Positioned barn | Expand för Cover-bilder |
| clipBehaviour | Clip.hardEdge, antiAlias, none | Beskärning av element utanför gränser | AntiAlias för rundade hörn |
I Flutter finns flera layout-widgets, var och en med sitt eget syfte. Stack skiljer sig från Row, Column och Container genom att den arbetar i tre dimensioner — x, y och z. Row och Column placerar element sekventiellt på en rad, medan Stack gör det möjligt att stapla dem. Enligt en undersökning från Flutter Community (2025) blandar nybörjarutvecklare ihop Stack och Overlay — den senare är avsedd för systemets popup-element (SnackBar, Tooltip), medan Stack är för skärmstruktur.
| Widget | Dimensioner | Stapla | Positionering | Användning |
|---|---|---|---|---|
| Stack | 2D + z-index | Ja | Positioned / alignment | Stapla, märken, lager |
| Row | 1D (horisontell) | Nej | mainAxisAlignment | Linjär arrangemang |
| Column | 1D (vertikal) | Nej | mainAxisAlignment | Lista med element uppifrån och ner |
| Overlay | 2D | Ja | Globalt | SnackBar, systemöverlägg |
Stack ritar underordnade element sekventiellt — den första tillagda widgeten finns på det nedre lagret, den sista på det övre lagret. Detta är analogt med z-index på webben: element med högre värde täcker lägre. I Flutter finns det ingen explicit zIndex-egenskap som på webben — staplingsordningen bestäms helt av ordningen för tillägg av barn till Stack:s lista. Enligt Flutter Engine Source (2025) använder Stack:s interna implementering en målaralgoritm med lagerkö via canvas.drawChild, vilket ger linjär komplexitet O(n) vid ritning.
Stack(
children: [
Container(
color: Colors.blue,
width: 200,
height: 200,
),
Container(
color: Colors.red,
width: 100,
height: 100,
),
],
)
I detta exempel är den blå kvadraten 200×200 bakgrunden, och den röda kvadraten 100×100 ovanpå den. Den röda containern visas på det övre lagret eftersom den lades till som andra. Flutter använder inte z-index som ett nummer — stapling styrs helt av positionen i children-listan.
Positioned är en omslutande widget som positionerar sitt barn inuti Stack med hjälp av koordinaterna top, left, right, bottom. Till skillnad från icke-Positioned underordnade element ignorerar Positioned-widgets Stack:s alignment-egenskap och placeras strikt enligt de givna koordinaterna. Enligt Flutter API Reference (2025) stöder Positioned även width och height för att tvinga fram storleken på det underordnade elementet oberoende av dess inre storlek.
Stack(
children: [
Container(
color: Colors.grey.shade200,
width: 300,
height: 300,
),
Positioned(
top: 20,
left: 20,
child: Text('Övre vänstra hörnet'),
),
Positioned(
bottom: 20,
right: 20,
child: Text('Nedre högra hörnet'),
),
],
)
Positioned accepterar värden i logiska pixlar (device-independent pixels). Skillnaden mellan Positioned(left: 0, right: 0, top: 0, bottom: 0) och Container(width: double.infinity, height: double.infinity) — Positioned sträcker ut det underordnade elementet exakt till Stack:s gränser, medan Container till den maximalt tillgängliga storleken inuti Stack.
IndexedStack är en underklass till Stack som endast visar ett underordnat element enligt det angivna indexet, men bevarar tillståndet för alla underordnade widgets i minnet. Detta är en grundläggande skillnad jämfört med växling genom villkorlig rendering (if-else eller visibility), där dolda widgets förstörs. Enligt Flutter Team (2025) rekommenderas IndexedStack för BottomNavigationBar och TabBar, där tillståndet för varje skärm måste bevaras.
IndexedStack(
index: 0,
children: [
HomeScreen(),
SearchScreen(),
ProfileScreen(),
],
)
När index växlas från 0 till 1 förblir HomeScreen i minnet och förlorar inte sitt tillstånd (rullning, inmatade data). IndexedStream använder RepaintBoundary-mekanismen för isolering av omritning — endast den aktiva skärmen får ett build-anrop. Detta minskar GPU-belastningen vid växling av flikar.
Låt oss titta på tre praktiska scenarier för användning av Stack i verkliga projekt. Märke för aviseringar ovanpå ikonen — ett klassiskt exempel på stapling med Positioned. Tooltip med positionering i förhållande till det överordnade elementet. Cover-bild med text över för artikelkort.
// Märkesindikator på aviseringsikonen
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,
),
),
),
),
],
)
I detta exempel placerar Positioned en röd cirkel-märke i det övre högra hörnet av aviseringsikonen. Parametrarna right: 0 och top: 0 förankrar märket vid Stack:s gränser. Padding inuti Container skapar utrymme runt texten så att siffran inte ligger mot cirkelns kant.
Vanliga frågor
Stack visar alla underordnade element samtidigt i form av lager, medan IndexedStack endast visar ett per index. IndexedStack bevarar tillståndet för alla dolda barn i minnet, vilket är praktiskt för BottomNavigationBar och TabBar. Enligt Flutter Docs (2025) använder IndexedStack samma ritmekanism som Stack, men tillämpar Offstage på inaktiva barn.
Använd Stack:s alignment-egenskap med Alignment.center. Om texten är ett icke-Positioned underordnat element centreras den automatiskt i Stack. Om texten är inuti Positioned, ställ in Positioned(left: 0, right: 0, top: 0, bottom: 0) och justering via textAlign-egenskapen i Text.
Stack och Overlay löser olika uppgifter. Stack är en layout-widget för att bygga skärmstruktur med lagerstapling. Overlay är ett globalt lager ovanför hela widgethierarkin för systemmeddelanden (SnackBar, Tooltip). Enligt Flutter Team (2025) använd Stack för vanliga gränssnitt och Overlay för tillfälliga aviseringar.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också