Understanding Responsive Design in Flutter: Creating Adaptive Apps for All Devices

Mobterest Studio
5 min readJul 21, 2023

--

Understanding Responsive Design in Flutter

In today’s technology-driven world, mobile app development demands adaptability to a wide range of devices with varying screen sizes and resolutions. Responsive design is a crucial concept in app development, as it ensures that the user interface (UI) and user experience (UX) remain consistent and visually appealing across all platforms. Flutter, a popular cross-platform mobile app development framework, offers robust tools to implement responsive design effectively. In this article, we will explore the principles of responsive design in Flutter and learn how to create adaptive apps that cater to diverse devices seamlessly.

Photo by Brandon Romanchuk on Unsplash

What is Responsive Design?

Responsive design is an approach to web and app development that aims to adapt the UI and UX to different screen sizes, orientations, and resolutions. The goal is to ensure that users have a consistent, user-friendly experience, regardless of the device they use. In the context of Flutter, responsive design goes beyond merely resizing widgets; it involves adjusting layouts, fonts, images, and other UI elements to optimize the app for different devices.

MediaQuery Widget

In Flutter, the MediaQuery widget plays a pivotal role in responsive design. It provides access to the device's dimensions, orientation, and other characteristics. By wrapping relevant parts of the UI in a MediaQuery widget, developers can obtain contextual information and make decisions about how to adjust the app's layout and components accordingly.

import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;

return Center(
child: Container(
width: screenWidth * 0.8,
height: 200,
color: _getBackgroundColor(screenWidth),
child: Center(
child: Text(
_getMessage(screenWidth),
style: TextStyle(fontSize: 20.0, color: Colors.white),
),
),
),
);
}

String _getMessage(double screenWidth) {
if (screenWidth >= 600) {
return "Welcome to our Large Screen";
} else if (screenWidth >= 400) {
return "Welcome to our Medium Screen";
} else {
return "Welcome to our Small Screen";
}
}

Color _getBackgroundColor(double screenWidth) {
if (screenWidth >= 600) {
return Colors.green;
} else if (screenWidth >= 400) {
return Colors.blue;
} else {
return Colors.red;
}
}
}

In this example, we calculate the device’s screen width using MediaQuery.of(context).size.width and use it to adjust the container's width dynamically (screenWidth * 0.8). Based on the screen width, we change the background color and the displayed message using the _getBackgroundColor and _getMessage methods, respectively.

When you run this app on different devices or resize the emulator, you will see that the app’s UI adapts to the screen size, displaying different messages and colors depending on the device’s width. This demonstrates how MediaQuery allows us to build responsive apps that provide a consistent and optimized user experience on various devices.

OrientationBuilder Widget

The OrientationBuilder widget is another essential tool that responds to changes in device orientation (portrait or landscape). By utilizing it, developers can create custom UIs for different orientations, ensuring that their apps look and function optimally regardless of the device's orientation.

import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Welcome to our App!',
style: TextStyle(fontSize: 24.0),
),
SizedBox(height: 20.0),
OrientationBuilder(
builder: (context, orientation) {
return Text(
orientation == Orientation.portrait
? 'Portrait Mode'
: 'Landscape Mode',
style: TextStyle(fontSize: 18.0),
);
},
),
],
),
);
}
}

The OrientationBuilder widget updates the text based on the device's orientation, ensuring a dynamic user experience.

Layouts and Constraints

Flutter offers various widgets to create responsive layouts. The most commonly used ones include Container, Row, Column, and Flex. These widgets allow developers to define the UI structure and adjust it dynamically based on the available space and screen size.

To enforce responsive constraints, Flutter introduces the concept of MediaQueryData and BoxConstraints. The example below shows how to use BoxConstraints

Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My App'),
),
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
if (constraints.maxWidth > 600) {
return DesktopLayout(); // Customize layout for larger screens
} else {
return MobileLayout(); // Customize layout for smaller screens
}
},
),
);
}

AspectRatio and FractionallySizedBox

Maintaining consistent aspect ratios is crucial to responsive design. The AspectRatio widget in Flutter allows developers to enforce a specific aspect ratio for a child widget, ensuring it retains its intended proportions across different screen sizes.

The FractionallySizedBox widget is another powerful tool to create responsive designs. It allows widgets to be sized relative to their parent's dimensions, making it easier to adapt to various screen sizes.

import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: FractionallySizedBox(
widthFactor: 0.8,
heightFactor: 0.4,
child: Container(
color: Colors.green,
child: Center(
child: Text(
'Responsive FractionallySizedBox',
style: TextStyle(fontSize: 20.0),
),
),
),
),
);
}
}

In this example, we use FractionallySizedBox to create a responsive container that occupies 80% of the available width and 40% of the available height, regardless of the device's screen size.

import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.8,
height: MediaQuery.of(context).size.height * 0.4,
color: Colors.blue,
child: AspectRatio(
aspectRatio: 16 / 9, // Set the desired aspect ratio (width / height)
child: Image.network(
'https://example.com/xxxxx', // Replace with your image URL
fit: BoxFit.cover,
),
),
),
);
}
}

In this example, we use the AspectRatio widget to wrap an Image.network widget. The AspectRatio widget ensures that the image maintains an aspect ratio of 16:9 (width:height) within its parent container. Regardless of the device's screen size, the image will maintain its intended proportions without distortion.

LayoutBuilder

The LayoutBuilder widget allows you to build different UI layouts based on the parent widget’s constraints. You can use this to customize the UI based on available width and height.

Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Responsive App'),
),
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
if (constraints.maxWidth > 600) {
return DesktopLayout(); // Customize layout for larger screens
} else {
return MobileLayout(); // Customize layout for smaller screens
}
},
),
);
}

Positioned and Stack

These allow for precise positioning. The positioning will adapt to the container’s dimensions, making it responsive to different screen sizes.

import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.8,
height: MediaQuery.of(context).size.height * 0.6,
color: Colors.blue,
child: Stack(
children: [
Positioned(
top: 20,
left: 20,
child: Text(
'Top Left',
style: TextStyle(fontSize: 20.0),
),
),
Positioned(
bottom: 20,
right: 20,
child: Text(
'Bottom Right',
style: TextStyle(fontSize: 20.0),
),
),
],
),
),
);
}
}

Conclusion

Responsive design is an essential aspect of mobile app development in Flutter. By embracing the principles and tools mentioned above and many more, developers can create adaptive apps that provide a seamless user experience across various devices, screen sizes, and orientations. Considering the diverse landscape of devices, responsive design is not just a preference but a necessity to succeed in the competitive app market. With Flutter’s powerful capabilities, developers have the means to build stunning, responsive apps that delight users on any device.

👏🏽 Give this story a CLAP

👉🏽 Subscribe for upcoming articles

💰 Access Free Mobile Development tutorials

🔔 Follow for more

See you on next article 👋

--

--

No responses yet