Skip to content
Blog

Responsive Layouts with OrientationBuilder in Flutter

How to use OrientationBuilder to seamlessly switch between portrait and landscape layouts, handle parent constraints, and avoid common layout traps.

Published on • November 1, 2026

AI Assistant

When adapting an application between vertical handset usage and widescreen landscape viewing, a one-size-fits-all layout rarely provides an optimal experience. In Flutter, OrientationBuilder provides an elegant, declarative way to alternate widget trees based on parent orientation (docs.flutter.dev).

In this article, we explain how OrientationBuilder functions, how it differs from device-level orientation, and practical patterns for multi-pane tablet layouts.

Understanding OrientationBuilder

The OrientationBuilder widget provides a builder callback that receives the BuildContext and the current Orientation:

OrientationBuilder(
  builder: (context, orientation) {
    if (orientation == Orientation.portrait) {
      return const MobileSingleColumnView();
    } else {
      return const SplitPaneMasterDetailView();
    }
  },
)

Orientation vs. Device Rotation: A Critical Distinction

A common misconception is that OrientationBuilder always checks the physical device angle. In reality, OrientationBuilder evaluates the aspect ratio of its parent widget’s constraints:

  • Orientation.portrait: If maxHeight >= maxWidth.
  • Orientation.landscape: If maxWidth > maxHeight.

This distinction is crucial for responsive apps: if an app is running in split-screen multitasking on iPadOS or Android tablets, OrientationBuilder will correctly report portrait mode if the app window is tall and narrow—even if the physical tablet is held horizontally!

Practical Pattern: Adaptive Grid vs. List

A classic use case is switching an item collection from a vertical ListView in portrait to a multi-column GridView in landscape:

OrientationBuilder(
  builder: (context, orientation) {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: orientation == Orientation.portrait ? 2 : 4,
        crossAxisSpacing: 12,
        mainAxisSpacing: 12,
      ),
      itemCount: items.length,
      itemBuilder: (context, index) => ItemCard(item: items[index]),
    );
  },
)

Best Practices

  • Combine with LayoutBuilder: For granular breakpoint logic (e.g. distinguishing compact phones from wide desktop windows), combine OrientationBuilder with LayoutBuilder to inspect exact pixel constraints.
  • Preserve State with Keys: When switching between distinct widget trees, attach explicit PageStorageKey or GlobalKey instances to preserve scroll offsets and user inputs across rotation events.

OrientationBuilder is a simple yet indispensable component in any Flutter developer’s responsive design toolkit.