What is Responsive Design?
Responsive design means that your app's layout adapts to the screen size and orientation of the device. It ensures that your app looks good and functions well on everything from small phones to large tablets, foldables, and desktop windows. In Flutter, there are several tools to achieve this: MediaQuery, LayoutBuilder, OrientationBuilder, and flexible widgets like Flexible and Expanded. This guide will teach you how to build truly responsive Flutter apps.
MediaQuery – The Device Screen
MediaQuery provides information about the current device's screen size, orientation, pixel density, and more. You can use it to get the screen dimensions and adjust your UI accordingly.
OrientationBuilder – Reacting to Orientation
OrientationBuilder rebuilds its child when the device orientation changes. It gives you the current Orientation (portrait or landscape). This is useful for switching between a vertical list and a grid, for example.
LayoutBuilder – Knowing Parent Constraints
LayoutBuilder gives you the constraints imposed by the parent widget. This is more powerful than MediaQuery because it reacts to the available space within the layout, not just the screen size. It's ideal for widgets that need to adapt to the space they're given (e.g., inside a drawer or a dialog).
FractionallySizedBox – Percentage‑Based Sizing
FractionallySizedBox sizes its child to a fraction of the available space. This is great for creating flexible layouts without hard‑coded pixel values.
Flexible and Expanded – Share Space Dynamically
Flexible and Expanded are used inside Row, Column, and Flex to distribute space among children. Expanded forces the child to fill the remaining space; Flexible allows the child to shrink to its natural size but still be flexible.
Responsive Breakpoints – Classic Approach
Define breakpoints to switch between layouts. Common breakpoints are:
- Mobile: < 600 dp
- Tablet: 600 – 1200 dp
- Desktop: > 1200 dp
Adaptive vs Responsive
Responsive design usually refers to the layout adapting to screen size (e.g., columns rearrange). Adaptive design goes further: it changes the UI components themselves to suit the platform (e.g., using Cupertino widgets on iOS vs Material on Android). Flutter makes it easy to create both:
Common Responsive Patterns
- Mobile: Single column, bottom navigation bar.
- Tablet: Two‑column layout with side navigation or a master‑detail view.
- Desktop: Multi‑column, side panels, keyboard shortcuts, larger spacing.
Best Practices
- Avoid hard‑coded pixel values; use percentages, flexible widgets, and layout builders.
- Test on multiple screen sizes (use device preview in Flutter DevTools).
- Use
MediaQuery.of(context).sizesparingly; preferLayoutBuilderwhen the size is needed within a subtree.
- Use
- Create reusable responsive widgets that accept width constraints.
- Use
MediaQuery'spaddingto respect safe areas (notches, status bars).
- Use
Common Mistakes
- Using
MediaQueryinside abuildmethod that rebuilds often – can cause performance issues; store values ininitStateor useLayoutBuilder.
- Using
- Not testing on different screen sizes – assumptions about layout may break.
- Using
Expandedinside aColumnwithoutFlexiblefor wrapping – may cause overflow.
- Using
- Hard‑coding font sizes – use
MediaQuery.textScaleror responsive font sizes.
- Hard‑coding font sizes – use
Key Takeaways
- Responsive design adapts layout to screen size and orientation.
- -
MediaQueryprovides screen dimensions and orientation. LayoutBuildergives you available space constraints from the parent.
OrientationBuilderreacts to device orientation changes.
- Use
Flexible,Expanded, andFractionallySizedBoxfor flexible sizing.
- Use
- Define breakpoints to switch between layouts.
- Always test on multiple devices and orientations.