Build Responsive LayoutBuilder and Adaptive GridView Layouts
Construct adaptive multi-screen dashboards that gracefully adjust column counts, padding, and font scales across 360px mobile, 768px tablet, and 1440px desktop displays.
1. The Core Challenge & Problem
2. Architectural Principles & Resolution
3. Complete Tested Flutter Code
main.dart (Flutter 3.x+ ready)import 'package:flutter/material.dart';
void main() => runApp(const MaterialApp(home: ResponsiveDashboardPage()));
class ResponsiveDashboardPage extends StatelessWidget {
const ResponsiveDashboardPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('T08.01: Responsive LayoutBuilder')),
body: LayoutBuilder(
builder: (context, constraints) {
// Use parent constraints rather than full window dimensions!
final isCompact = constraints.maxWidth < 600;
final isTablet = constraints.maxWidth >= 600 && constraints.maxWidth < 1024;
final padding = isCompact ? 12.0 : isTablet ? 20.0 : 32.0;
return Padding(
padding: EdgeInsets.all(padding),
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Text(
isCompact ? 'Mobile View (< 600px)' : isTablet ? 'Tablet View (600px - 1024px)' : 'Desktop View (> 1024px)',
style: TextStyle(
fontSize: isCompact ? 18 : 24,
fontWeight: FontWeight.bold,
color: const Color(0xFF0F172A),
),
),
),
),
// SliverGrid with maxCrossAxisExtent auto-computes optimal column counts!
SliverGrid(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 260.0,
mainAxisSpacing: 16.0,
crossAxisSpacing: 16.0,
childAspectRatio: 1.2,
),
delegate: SliverChildBuilderDelegate(
(context, index) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE2E8F0)),
boxShadow: const [
BoxShadow(color: Color(0x0A000000), blurRadius: 10, offset: Offset(0, 4)),
],
),
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
backgroundColor: const Color(0xFFEFF6FF),
child: Icon(Icons.dashboard_customize, color: const Color(0xFF2563EB)),
),
const Spacer(),
Text('Module ${index + 1}', style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
const SizedBox(height: 4),
Text('Adaptive Card', style: TextStyle(color: Colors.grey[600], fontSize: 13)),
],
),
);
},
childCount: 8,
),
),
],
),
);
},
),
);
}
} 4. Expected Visual & Behavioral Result
5. Common Pitfalls & Traps
Pitfall #1: Using MediaQuery.of(context).size.width inside reusable cards or sidebar components
Remedy: MediaQuery returns whole-window width, causing nested cards to think they have 1440px of width even when placed inside a 300px sidebar drawer. Always use LayoutBuilder for component-level constraints.
Pitfall #2: Setting fixed pixel crossAxisSpacing without scaling padding
Remedy: Use maxCrossAxisExtent to allow the grid engine to compute ideal item counts automatically.
Pitfall #3: Nesting an unconstrained GridView inside a Column without shrinkWrap or Expanded
Remedy: Always place grids in an Expanded widget or use CustomScrollView with SliverGrid to ensure proper bounded scrolling.