Flexible — en Flutter-widget som styr hur underordnat element tar upp tillgängligt utrymme i en Flex-behållare. Till skillnad från Expanded tvingar inte Flexible barnet att fylla hela det tilldelade området — den underordnade widgeten kan vara mindre och resterande utrymme förblir tomt. Enligt officiell Flutter-dokumentation (2026) är Flexible nödvändigt i scenarier som kräver flexibel utrymmesfördelning utan tvingande utsträckning: knappar med minimal bredd, textblock med naturlig storlek och element med intrinsic constraints.
Huvudpunkter
Flexible — en omslags-widget som ger det underordnade elementet flexibelt utrymme i en Flex-behållare. Flexible, liksom Expanded, deltar i fördelningen av ledigt utrymme, men med en viktig skillnad: barnet till Flexible kan ta upp mindre utrymme än tilldelat, om dess egen storlek är mindre än tillgängligt utrymme.
Flexible använder Flutters Flex-algoritm för att beräkna tillgängligt utrymme. Först frågar ramverket alla icke-flexibla barn (widgetar utan Flexible/Expanded) och beräknar deras intrinsic size. Det återstående utrymmet delas mellan de flexibla barnen proportionellt mot deras flex-faktor. Efter utrymmestilldelning kontrollerar Flexible fit — om det är loose, tillämpas begränsningen ”inte mer än tilldelat” på det underordnade elementet, vilket gör att det kan förbli litet.
Egenskap hos Flexible: om den underordnade widgeten har egna minimimått (till exempel Text med en lång sträng), tilldelar Flexible det begärda utrymmet, utan att tvingande sträcka ut det. Detta gör Flexible oersättlig för element vars storlek bör bestämmas av innehållet, inte av behållaren.
Slutsats: använd Flexible när du behöver reservera utrymme för ett element, men inte tvinga det att sträcka ut sig. Detta bevarar innehållets naturliga storlek vid flexibel layoutfördelning.
FlexFit — en uppräkning av två värden: tight och loose. Av valet av fit beror om den underordnade widgeten kommer att tvingas sträckas till storleken av det tilldelade utrymmet.
FlexFit.tight: det underordnade elementet får tight constraints — minsta och största storlek är lika med tilldelat utrymme. Barnet måste ta upp exakt så mycket utrymme som Flex-algoritmen tilldelade. Om barnet är mindre — sträcks det. Om det är större — komprimeras det. Beteende identiskt med Expanded.
FlexFit.loose: det underordnade elementet får loose constraints — minsta storlek är 0, största är lika med tilldelat utrymme. Barnet kan vara av valfri storlek från 0 till maximum. Om barnet är litet (till exempel Text med en kort sträng), tar det sin naturliga bredd, och resten av utrymmet förblir tomt.
Slutsats: FlexFit.loose — val för textblock och element med naturlig storlek. FlexFit.tight — för strikta kolumnlayouter där alla element måste ha samma bredd eller höjd.
Flexible och Expanded ser lika ut, men löser olika uppgifter. Expanded sträcker alltid barnet över hela tillgängliga utrymmet. Flexible kan lämna tomt utrymme runt barnet om innehållets storlek är mindre än den tilldelade andelen.
Scenario för Flexible: inuti en Row finns två knappar. Den första — “Köp” (kort text), den andra — “Lägg i varukorg” (lång text). Med Expanded kommer båda knapparna att sträckas till samma bredd och den korta texten får enorma marginaler. Med Flexible tar varje knapp sin texts bredd och det lediga utrymmet förblir mellan dem eller vid kanterna.
Scenario för Expanded: inuti en Column finns tre kort som måste ha samma höjd oavsett innehåll. Expanded delar jämnt på tillgänglig höjd och varje kort sträcks till samma storlek. Flexible med loose passar inte här — ett litet kort förblir litet och bryter den enhetliga designen.
Slutsats: välj Flexible när innehållet bestämmer elementets storlek och tomt utrymme runt det är acceptabelt. Välj Expanded när alla element måste ha samma storlek oavsett innehåll.
Exempel 1 visar grundläggande användning av Flexible med FlexFit.loose i en Row.
Row(
children: [
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.amber,
child: const Text('kort'),
),
),
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.cyan,
child: const Text('lång text för demo'),
),
),
],
)
I exemplet båda Flexible med loose fit. Den första behållaren med kort text tar sin naturliga bredd. Den andra med lång text — sin bredd. Row tilldelar varje hälften av tillgänglig bredd, men loose fit tillåter behållarna att vara mindre och det lediga utrymmet förblir tomt mellan dem.
Exempel 2 — jämförelse av Flexible med Tight och Loose fit i en Column.
Column(
children: [
Flexible(
fit: FlexFit.tight,
child: const Card(
child: ListTile(
title: Text('Tight — sträckt till full höjd'),
),
),
),
const SizedBox(
height: 8,
),
Flexible(
fit: FlexFit.loose,
child: const Card(
child: ListTile(
title: Text('Loose — naturlig höjd'),
),
),
),
],
)
I Column sträcker den första Flexible (tight) Cardet till halva tillgängliga höjden. Den andra Flexible (loose) — Cardet tar höjd efter innehåll och resten av utrymmet förblir tomt. Visuellt syns hur tight tvingande fyller området medan loose behåller kompakt storlek.
Slutsats: i produktionskod används Flexible med loose för formulärfält, knappar och textblock. Flexible med tight — motsvarighet till Expanded, används för jämn fördelning.
Misstag 1: användning av Flexible utanför Flex-behållare. Liksom Expanded kastar Flexible ett LayoutException om det inte finns inuti Row, Column eller Flex. Lösning: kontrollera alltid widgetarnas föräldrakoppling.
Misstag 2: förväxling mellan Flexible och Expanded. Utvecklare använder ofta Expanded när Flexible med loose fit behövs och tvärtom. Resultat: Expanded sträcker elementet med kort text och skapar stora tomma fält. Lösning: om elementets storlek kan vara mindre än tilldelat utrymme — använd Flexible(fit: FlexFit.loose).
Misstag 3: noll flex-faktor. Flexible med flex=0 beter sig som en icke-flexibel widget, vilket kan vara otydligt. Utvecklaren förväntar sig flexibelt beteende men elementet tar minimal storlek. Lösning: flex bör vara ≥1 för aktiv utrymmesfördelning.
Misstag 4: Flexible inuti ScrollView utan storleksbegränsning. Om Flexible finns i Column inuti SingleChildScrollView ger scroll-behållaren oändligt utrymme och flex-fördelningen fungerar inte. Lösning: begränsa scroll-behållarens storlek via SizedBox eller ConstrainedBox.
Slutsats: Flexible kräver samma uppmärksamhet på föräldrakontext som Expanded. Skillnaden är bara i fit — välj medvetet beroende på uppgiften.
Vanliga frågor
Expanded — är Flexible med fast fit=tight. Skillnaden är att Expanded har en styv koppling till att fylla hela tillgängliga utrymmet, medan Flexible kan använda loose fit för att bevara barnets naturliga storlek.
För knappar med olika textlängd, använd Flexible(fit: FlexFit.loose). Varje knapp tar bredd efter innehåll och det blir ingen disproportion mellan dem. Expanded gör alla knappar lika breda.
Ställ in fit: FlexFit.tight — Flexible tvingar barnet att fylla hela det tilldelade utrymmet. I detta läge är Flexible helt identisk med Expanded i beteende.
Ja, om barnet är större än tilldelat utrymme. Flexible överför constraints med maximal storlek lika med Flex-behållarens andel. Om barnet överskrider denna storlek komprimeras det inom constraints.
Ja, Flexible fungerar med alla Flex-behållare, inklusive Row, Column och baswidgeten Flex med godtycklig direction. Flex tillåter inställning av icke-standardriktningar via mainAxisAlignment och crossAxisAlignment.
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å