Building Responsive Layouts in Flutter: Complete Guide
Creating responsive applications that work well across different screen sizes and orientations is crucial for modern app development. Flutter provides powerful tools to build highly responsive UIs. This guide covers key techniques to make your Flutter app look great on any device.

1. Using MediaQuery for Screen-Aware Layouts
MediaQuery gives you access to the current screen metrics, enabling you to make decisions based on available space:
Widget build(BuildContext context) {
// Get the screen size
final screenSize = MediaQuery.of(context).size;
// Adapt layout based on width
return Scaffold(
body: screenSize.width > 600
? _buildWideLayout()
: _buildNarrowLayout(),
);
}
Widget _buildWideLayout() {
return Row(
children: [
Expanded(flex: 1, child: LeftPanel()),
Expanded(flex: 2, child: ContentPanel()),
],
);
}
Widget _buildNarrowLayout() {
return Column(
children: [
ContentPanel(),
BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: "Home",
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: "Settings",
),
],
),
],
);
}
2. Using LayoutBuilder for Container-Constrained Widgets
LayoutBuilder provides the parent widget's constraints, allowing you to build different layouts based on available space:
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
if (constraints.maxWidth > 600) {
return _buildWideWidget();
} else {
return _buildNarrowWidget();
}
},
);
}
3. Flexible and Expanded Widgets
Use these widgets to create layouts that allocate space dynamically:
Row(
children: [
// Takes 30% of the available width
Flexible(
flex: 3,
child: Container(color: Colors.red),
),
// Takes 70% of the available width
Flexible(
flex: 7,
child: Container(color: Colors.blue),
),
],
)
4. AspectRatio Widget for Consistent Proportions
Maintain a specific aspect ratio regardless of screen size:
AspectRatio(
aspectRatio: 16 / 9,
child: Container(
color: Colors.green,
child: Center(
child: Text("16:9 Aspect Ratio"),
),
),
)
5. FittedBox for Scaling Content
Scale content to fit within available space:
Container(
width: 200,
height: 100,
color: Colors.grey[300],
child: FittedBox(
fit: BoxFit.contain,
child: Text(
"This text will scale to fit",
style: TextStyle(fontSize: 50),
),
),
)
Best Practices
- Test your UI on multiple screen sizes throughout development
- Use device previews or the Flutter DevTools to simulate different devices
- Consider orientation changes and handle them appropriately
- Use SafeArea to avoid system UI overlaps like notches and status bars
- Prefer relative sizing over absolute pixel values whenever possible
Complete Example: Responsive Grid Layout
This example demonstrates a grid that adapts its column count based on screen width:
class ResponsiveGridExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Responsive Grid")),
body: LayoutBuilder(
builder: (context, constraints) {
// Calculate columns based on available width
int crossAxisCount = _getCrossAxisCount(constraints.maxWidth);
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount,
childAspectRatio: 1.0,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
),
padding: EdgeInsets.all(10.0),
itemCount: 20,
itemBuilder: (context, index) {
return Card(
color: Colors.blue[(index % 8 + 1) * 100],
child: Center(
child: Text(
"Item $index",
style: TextStyle(color: Colors.white),
),
),
);
},
);
},
),
);
}
int _getCrossAxisCount(double width) {
if (width > 1200) return 6;
if (width > 900) return 5;
if (width > 600) return 4;
if (width > 300) return 3;
return 2;
}
}
Building responsive UIs in Flutter is achievable with the right combination of widgets and layout strategies. By using MediaQuery, LayoutBuilder, and flexible widgets, you can create applications that provide optimal user experiences across all device sizes.