Het probleem
Een Flutter-app die naar telefoons, tablets en desktop gaat, heeft meer nodig dan een flexibele kolom. Een scherm dat prettig leest bij 390 logische pixels breed wil bij 700 een gecentreerde kaart en bij 1200 een zijbalk. Flutter geeft je de metingen, maar geen structuur om ernaar te handelen.
Dus verspreiden de controles zich. Hier een MediaQuery.of(context).size.width > 600, daar een LayoutBuilder, en drie widgets verderop een ternaire operator binnen een Padding. Elk daarvan is op zichzelf te verdedigen; samen vormen ze een lay-outbeleid dat nergens op één plek staat opgeschreven.
Veelvoorkomende problemen:
- Breekpuntwaarden die in tientallen widgets zijn gedupliceerd en uit elkaar lopen naarmate het ontwerp verandert
LayoutBuilderdie de beperkingen van de ouder meldt terwijl je het toestel wilde weten- Lay-outs die naar de tabletvariant omslaan zodra een telefoon liggend wordt gedraaid
- Widgetbomen waarin de responsieve vertakking onzichtbaar is zonder elk kind te lezen
Hoe flutter_adaptive_layout dat oplost
AdaptiveLayout neemt één builder per schermgrootte en een child. Het meet het toestel via MediaQuery, vertaalt dat naar een ScreenSize, en bouwt alleen de passende variant — waarbij de child één keer wordt gemaakt en aan de winnende builder wordt overhandigd.
AdaptiveLayout(
smallBuilder: (context, child) => child!,
mediumBuilder: (context, child) => Center(child: child),
largeBuilder: (context, child) => Row(
children: [const Sidebar(), Expanded(child: child!)],
),
child: const MyHomePage(),
)
Het responsieve besluit leeft nu in één widget, bovenaan de subboom die het bestuurt, geschreven als drie lay-outs in plaats van een keten voorwaarden.


Wat het ondersteunt
- Lay-outs gestuurd door schermgrootte —
smallBuilder,mediumBuilderenlargeBuilder, elk optioneel; een ontbrekende valt terug opchild, zodat je alleen de groottes hoeft vorm te geven waar het je om gaat - Breekpunten die jij bepaalt — standaard 400 en 600 logische pixels, per widget of voor de hele app te overschrijven
- Bouw de child één keer — van lay-out wisselen verpakt je inhoud in plaats van haar opnieuw op te bouwen
- Stabiel bij draaien — de indeling leest
MediaQuery.of(context).size.shortestSide, zodat een telefoon liggend klein blijft - Inwisselbare indelingslogica — implementeer
ScreenSizeQualifierom in te delen op breedte, platform, scharnierstand of wat je designsysteem ook gebruikt - Geen afhankelijkheden — puur Flutter boven op
MediaQuery, werkend op iOS, Android, web, macOS, Windows en Linux
Hoe de schermgrootte wordt bepaald
De standaard BreakpointsQualifier vergelijkt de kortste zijde met twee breekpunten, inclusief — een waarde die precies gelijk is aan een breekpunt hoort bij de kleinere categorie.
| Schermgrootte | Voorwaarde | Standaardbereik | Typisch toestel |
|---|---|---|---|
ScreenSize.small | shortestSide <= smallBreakpoint | 0–400 logische pixels | Telefoons |
ScreenSize.medium | shortestSide <= mediumBreakpoint | 401–600 logische pixels | Kleine tablets |
ScreenSize.large | boven mediumBreakpoint | 601+ logische pixels | Grote tablets, desktop |
Breekpunten worden in een vaste volgorde opgelost, waarbij de eerst gevonden waarde wint: de argumenten die aan BreakpointsQualifier zijn meegegeven, dan de dichtstbijzijnde BreakpointsSetting erboven, dan de ingebouwde 400 en 600.
Toepassingen in de praktijk
Telefoon-eerst-apps die een tabletversie krijgen
Een app die op telefoons begon kan elk scherm houden dat er al is en een largeBuilder toevoegen waar een bredere lay-out loont. Schermen zonder builder voor een bepaalde grootte renderen de child ongewijzigd, zodat de migratie scherm voor scherm gaat in plaats van in één keer.
Navigatie met overzicht en detail
Een lijst die op een telefoon een detailroute opduwt, kan op een tablet lijst en detail naast elkaar tonen. De twee varianten staan naast elkaar gedeclareerd in één widget, waardoor het verschil ertussen in een diff te beoordelen is.
Designsystemen met eigen breekpunten
Wikkel MaterialApp één keer in BreakpointsSetting en elke AdaptiveLayout in de boom neemt de getallen van het designsysteem over. Ze later wijzigen is een aanpassing van één regel, geen zoektocht door de codebase.
Vensters op web en desktop
Op web en desktop is de gemeten grootte het venster, dus lay-outs reageren terwijl de gebruiker het formaat verandert — hetzelfde codepad dat een tablet afhandelt, handelt een verkleinde browser af.
Aan de slag
Installeer het pakket:
flutter pub add flutter_adaptive_layout
Vereist Dart >=2.18.5 <4.0.0 en Flutter 1.17+.
Importeer het daarna en wikkel de widget waarvan de lay-out zich moet aanpassen:
import 'package:flutter_adaptive_layout/flutter_adaptive_layout.dart';
AdaptiveLayout(
largeBuilder: (context, child) => Center(
child: SizedBox(width: 600, child: child),
),
child: const ArticleView(), // used as-is on small and medium screens
)
Wil je schermen anders indelen, implementeer dan ScreenSizeQualifier en geef die mee als qualifier:
class WidthQualifier extends ScreenSizeQualifier {
@override
ScreenSize qualify(BuildContext context) {
final width = MediaQuery.of(context).size.width;
if (width < 600) return ScreenSize.small;
if (width < 1024) return ScreenSize.medium;
return ScreenSize.large;
}
}
qualify draait bij elke build, dus houd hem goedkoop en vrij van neveneffecten.
Een complete, draaibare app staat in de voorbeeldmap.