Building Responsive UI with MediaQuery and OrientationBuilder in Flutter
Hello, fellow Flutter enthusiasts! ๐ I'm here to talk about something that will take your Flutter app development skills up a notch - building responsive user interfaces. Whether you're working on a smartphone or a tablet, ensuring your app looks great on any device is crucial. Today, we're diving into two powerful tools: MediaQuery
and OrientationBuilder
. Let's make our apps shine everywhere!
Unveiling the Power of MediaQuery
What's MediaQuery, Anyway?
Think of MediaQuery
as your secret agent. It whispers important device details to you, helping you tailor your app to the user's environment. Let's unlock its potential step by step.
Accessing MediaQuery
To summon our trusty agent, we simply call MediaQuery.of(context)
. It provides us with a wealth of information about the device and screen.
final mediaQueryData = MediaQuery.of(context);
Discovering Screen Size
Want to know the dimensions of the screen your app is running on? MediaQuery
is here to help:
final screenWidth = mediaQueryData.size.width;
final screenHeight = mediaQueryData.size.height;
Checking Orientation
Is the user holding their device in portrait or landscape mode? MediaQuery
can give you the answer:
final isPortrait = mediaQueryData.orientation == Orientation.portrait;
Grasping Device Pixel Ratio
Pixel density matters, especially when dealing with images and text sizes. MediaQuery
reveals the device's pixel ratio:
final pixelRatio = mediaQueryData.devicePixelRatio;
Embrace the Versatility of OrientationBuilder
OrientationBuilder: Your Layout Acrobat
Imagine your app's layout effortlessly flipping and rearranging itself as the user rotates their device. That's the magic of OrientationBuilder
. Let's bring our UI to life with it!
Wrapping Your Widgets
To start using OrientationBuilder
, wrap your widgets in it. This wizardry will provide you with the current orientation as a parameter:
OrientationBuilder(
builder: (context, orientation) {
// Your layout logic goes here.
},
)
Adapting to Orientation Changes
Now, let's get practical. Here's how you can switch your UI elements based on the device's orientation:
OrientationBuilder(
builder: (context, orientation) {
if (orientation == Orientation.portrait) {
// Show portrait UI.
} else {
// Show landscape UI.
}
},
)
Putting It All Together: Practical Examples
Let's bring our newfound knowledge to life with some real-world scenarios.
Scenario 1: A Weather App
Imagine you're developing a weather app. You want to display a five-day forecast on larger screens but switch to a simplified single-day view on smaller devices. Here's how you can do it:
if (mediaQueryData.size.width > 600) {
return WideScreenLayout();
} else {
return NarrowScreenLayout();
}
Scenario 2: A Reading App
Now, picture a reading app. In portrait mode, you want to focus on the text. However, in landscape mode, you'd like to display additional information alongside the text. OrientationBuilder
makes it easy:
OrientationBuilder(
builder: (context, orientation) {
if (orientation == Orientation.portrait) {
return TextReader();
} else {
return DetailedReadingLayout();
}
},
)
Share Your Responsive Creations
With MediaQuery
and OrientationBuilder
, crafting responsive Flutter apps is a breeze. You can create layouts that adapt seamlessly to any device or screen size. So go ahead, experiment, and create pixel-perfect, adaptable UIs!
Now that you're armed with these tools, it's time to share your responsive creations with the world. Let's make Flutter apps look fantastic on every device. Happy coding! ๐ฑ๐ปโจ
Note: This blog post is inspired by personal experiences and Flutter's official documentation.
Full Code for Reference
Here's the full code to help you on your responsive journey:
main.dart:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
//home: const Media(),
home: const Oriten(),
);
}
}
media.dart:
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class Media extends StatefulWidget {
const Media({Key? key});
@override
State<Media> createState() => _MediaState();
}
class _MediaState extends State<Media> {
@override
Widget build(BuildContext context) {
final mediaQueryData = MediaQuery.of(context);
final screenWidth = mediaQueryData.size.width;
final screenHeight = mediaQueryData.size.height;
final isPortrait = mediaQueryData.orientation == Orientation.portrait;
final pixelRatio = mediaQueryData.devicePixelRatio;
return Scaffold(
appBar: AppBar(
title: const Text('Media'),
),
body: SingleChildScrollView(
child: Column(
children: [
Text(
"Hello, this is a text",
style: GoogleFonts.rubikIso(
fontSize: isPortrait ? 20 : 16,
color: Colors.green[300],
),
),
// Add your widgets here to try.
],
),
),
);
}
}
orientation.dart:
import 'package:flutter/material.dart';
class Oriten extends StatefulWidget {
const Oriten({Key? key});
@override
State<Oriten> createState() => _OritenState();
}
class _OritenState extends State<Oriten> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Orientation'),
centerTitle: true,
),
body: OrientationBuilder(
builder: (context, orientation) {
if (orientation == Orientation.portrait) {
return PortraitLayout();
} else {
return LandscapeLayout();
}
},
),
);
}
}
class PortraitLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Portrait Mode",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 20,
),
Icon(
Icons.mobile_friendly,
size: 100,
),
],
);
}
}
class LandscapeLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Landscape Mode",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 20,
),
Icon(
Icons.laptop_windows,
size: 100,
),
],
);
}
}
Remember to adjust and expand on this code according to your app's specific requirements.
Video: https://youtu.be/otmsUXamIOk (in Hindi)