How to Build Responsive Layouts in Flutter Using LayoutBuilder and MediaQuery

Use LayoutBuilder to inspect constraints.maxWidth and MediaQuery.sizeOf(context) to measure window dimensions, enabling you to return different widget trees based on actual available space rather than physical device type.

Building responsive layouts in Flutter requires reacting to the app's window size across mobile, tablet, and desktop form factors. According to the flutter-build-responsive-layout skill in the flutter/skills repository, you should base layout decisions on available window space rather than hardcoding device types. This approach ensures your UI adapts automatically to resizable windows, foldables, and varying screen sizes without overflow errors.

Measuring the App Window with MediaQuery

The first step in responsive design is obtaining the exact dimensions of the application window. Use MediaQuery.sizeOf(context) to retrieve the current window size, which works consistently across all platforms.

According to the skill definition in skills/flutter-build-responsive-layout/SKILL.md at lines 21-23, this method provides the precise measurements needed to make informed layout decisions. However, avoid using MediaQuery.orientationOf or OrientationBuilder near the top of your widget tree, as orientation does not always reflect the true available window space—especially on foldable devices or resizable desktop windows (lines 23-24).

Implementing Breakpoints with LayoutBuilder

Wrap your widget tree in a LayoutBuilder to access the BoxConstraints passed down by the parent. Inspect constraints.maxWidth to implement breakpoints and return completely different layouts based on the available width.

The skill documentation at lines 22-23 recommends this approach because it allows you to handle breakpoint logic declaratively within the build method. Define a logical threshold—such as largeScreenMinWidth = 600.0—and switch between layouts when constraints.maxWidth exceeds this value.

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)),
        VerticalDivider(width: 1),
        Expanded(child: Placeholder(color: Colors.green)),
      ],
    );
  }

  Widget _buildSmallScreenLayout() {
    return const Placeholder(color: Colors.green);
  }
}

Excerpt from skills/flutter-build-responsive-layout/SKILL.md (lines 72-90).

Distributing Space with Expanded and Flexible

For fluid layouts inside rows, columns, or other flex containers, use Expanded to force a child to fill remaining space or Flexible for proportional sizing. This keeps the layout adaptive when the parent container changes size.

The skill lists these patterns at lines 29-32 in SKILL.md, emphasizing that these widgets work in concert with LayoutBuilder to create truly responsive designs. Use Expanded when you need a child to take all remaining space, and Flexible with a flex factor when you need proportional distribution.

Constraining Width on Large Screens

Prevent content like ListView or GridView from stretching uncomfortably across wide desktop windows by wrapping them in a ConstrainedBox with a sensible maxWidth. Center the constrained content for a polished appearance.

As documented in the "Constraining Width on Large Screens" section (lines 33-36), this technique ensures readability on large monitors while maintaining responsiveness.

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),
          child: ListView.builder(
            itemCount: 50,
            itemBuilder: (context, index) {
              return ListTile(title: Text('Item $index'));
            },
          ),
        ),
      ),
    );
  }
}

Excerpt from skills/flutter-build-responsive-layout/SKILL.md (lines 112-126).

Summary

  • Use LayoutBuilder to inspect constraints.maxWidth for breakpoint logic rather than relying on device type detection.
  • Access window dimensions via MediaQuery.sizeOf(context) as defined at lines 21-23 of the skill file.
  • Avoid MediaQuery.orientationOf and OrientationBuilder for layout decisions, as orientation doesn't guarantee available space on foldables or resizable windows (lines 23-24).
  • Leverage Expanded and Flexible (lines 29-32) to distribute space fluidly within flex containers.
  • Wrap wide content in ConstrainedBox with maxWidth constraints (lines 33-36) to maintain readability on large screens.

Frequently Asked Questions

Should I use LayoutBuilder or MediaQuery for responsive layouts?

Use LayoutBuilder when you need to know the constraints provided by the immediate parent widget, and MediaQuery.sizeOf(context) when you need the overall application window size. For most responsive breakpoint logic, LayoutBuilder is preferred because it reacts to the actual space available to the widget, whereas MediaQuery provides the total screen or window dimensions.

Why should I avoid OrientationBuilder for responsive design?

According to the flutter/skills documentation (lines 23-24), orientation does not always reflect the true available window space, particularly on foldable devices or resizable desktop windows. A device might be in landscape orientation but have limited width due to split-screen mode or folding, making width-based constraints more reliable than orientation checks.

The skill recommends defining a logical width threshold such as largeScreenMinWidth = 600.0. When LayoutBuilder's constraints.maxWidth exceeds this value, you can present a desktop-optimized layout (such as side navigation), and fall back to a mobile layout (single column) when below this threshold.

How do I prevent my content from stretching too wide on desktop screens?

Wrap your scrollable widgets like ListView or GridView in a ConstrainedBox with a maxWidth parameter (commonly 800.0), and center the constrained box using the Center widget. As shown in lines 33-36 of the skill file, this prevents text and UI elements from stretching across the entire width of large monitors while maintaining responsiveness.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →