Building Responsive UI in Flutter: From Phone to Tablet and Desktop

A good Flutter app should look great on a small phone, a tablet and a desktop window. Learn how to get there with LayoutBuilder, breakpoints, adaptive navigation and correct right-to-left support.

3 min read1 views
Building Responsive UI in Flutter: From Phone to Tablet and Desktop

A Flutter app might open on a 5-inch phone, a tablet, a Windows window or a browser. Hard-code the layout and one of them will break. Luckily Flutter has good tools for responsive UI.

#Read the available size

For the size of the whole window:

final width = MediaQuery.sizeOf(context).width;

But sometimes the layout should react to its parent's space, not the screen; LayoutBuilder is better there:

LayoutBuilder(
  builder: (context, constraints) {
    final isWide = constraints.maxWidth >= 840;
    return isWide ? const WideLayout() : const NarrowLayout();
  },
)

#Breakpoints

Material guidance suggests these values, and they are a good start:

  • under 600: phone (compact)
  • 600 to 840: small tablet (medium)
  • 840 and up: large tablet and desktop (expanded)

#Adaptive navigation

A bottom NavigationBar works best on phones and a side NavigationRail on wide screens:

Widget build(BuildContext context) {
  final wide = MediaQuery.sizeOf(context).width >= 600;
  return Scaffold(
    body: Row(
      children: [
        if (wide) NavigationRail(
          selectedIndex: index,
          onDestinationSelected: onSelect,
          destinations: railItems,
        ),
        Expanded(child: pages[index]),
      ],
    ),
    bottomNavigationBar: wide ? null : NavigationBar(
      selectedIndex: index,
      onDestinationSelected: onSelect,
      destinations: barItems,
    ),
  );
}

#An automatic grid instead of a fixed column count

GridView.builder(
  gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
    maxCrossAxisExtent: 280,
    mainAxisSpacing: 12,
    crossAxisSpacing: 12,
  ),
  itemBuilder: (context, i) => ProductCard(items[i]),
)

The number of columns adapts to the width by itself.

#Limit content on big screens

A form that spans a 27-inch monitor looks ugly and is hard to read. Wrap it in ConstrainedBox(constraints: BoxConstraints(maxWidth: 900)) and a Center.

#Common mistakes

  • Fixed heights on cards containing text: a user who enlarged the system font sees an overflow. Use Expanded, Flexible and content-sized layouts.
  • Assuming a fixed width: always test several sizes (360, 412, 820, 1440).

#Right-to-left support (Persian and Arabic)

  • Use EdgeInsetsDirectional.only(start: ...) instead of EdgeInsets.only(left: ...).
  • Use AlignmentDirectional.centerStart instead of Alignment.centerLeft.
  • Check directional icons (such as a back arrow) against Directionality.

With these few principles, a single codebase looks professional on phone, web and desktop.

Learn Flutter the professional, project-based way

The FastFlutter VIP course takes you from zero to a published app, with direct support from the instructor.

View the VIP course