Use `LayoutBuilder`, `MediaQuery`, or `Expanded/Flexible` to create a layout that adapts to different screen sizes. Use when you need the UI to look good on both mobile and tablet/desktop form factors.
MediaQuery.sizeOf(context) to get the size of the entire app window.LayoutBuilder to make layout decisions based on the parent widget's allocated space. Evaluate constraints.maxWidth to determine the appropriate widget tree to return.MediaQuery.orientationOf or OrientationBuilder near the top of the widget tree to switch layouts. Device orientation does not accurately reflect the available app window space.Expanded and Flexible within Row, Column, or Flex widgets.
Expanded to force a child to fill all remaining available space (equivalent to Flexible with fit: FlexFit.tight and a flex factor of 1.0).Flexible to allow a child to size itself up to a specific limit while still expanding/contracting. Use the flex factor to define the ratio of space consumption among siblings.GridView or ListView in a ConstrainedBox or Container and define a maxWidth in the BoxConstraints.ListView.builder or GridView.builder when rendering lists with an unknown or large number of items.Display API to retrieve physical screen dimensions instead of MediaQuery. MediaQuery fails to receive the larger window size in compatibility modes.BoxConstraints.LayoutBuilder.constraints.maxWidth from the builder callback.largeScreenMinWidth = 600).maxWidth > largeScreenMinWidth: Return a large-screen layout (e.g., a Row placing a navigation sidebar and content area side-by-side).maxWidth <= largeScreenMinWidth: Return a small-screen layout (e.g., a Column or standard navigation-style approach).ListView, text blocks, forms).ListView.builder to GridView.builder using SliverGridDelegateWithMaxCrossAxisExtent to automatically adjust column counts based on window size.ConstrainedBox.BoxConstraints(maxWidth: [optimal_width]) to the ConstrainedBox.ConstrainedBox in a Center widget to keep the constrained content centered on large screens.maxWidth or grid extents.import 'package:flutter/material.dart';
const double largeScreenMinWidth = 600.0;
class AdaptiveLayout extends StatelessWidget {
const AdaptiveLayout({super.key});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > largeScreenMinWidth) {
return _buildLargeScreenLayout();
} else {
return _buildSmallScreenLayout();
}
},
);
}
Widget _buildLargeScreenLayout() {
return Row(
children: [
const SizedBox(width: 250, child: Placeholder(color: Colors.blue)),
const VerticalDivider(width: 1),
Expanded(child: const Placeholder(color: Colors.green)),
],
);
}
Widget _buildSmallScreenLayout() {
return const Placeholder(color: Colors.green);
}
}
import 'package:flutter/material.dart';
class ConstrainedContent extends StatelessWidget {
const ConstrainedContent({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 800.0, // Maximum width for readability
),
child: ListView.builder(
itemCount: 50,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
),
),
),
);
}
}