DEV Community

raman04-byte
raman04-byte

Posted on • Originally published at raman04.hashnode.dev

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);

Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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.
  },
)

Enter fullscreen mode Exit fullscreen mode

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.
    }
  },
)

Enter fullscreen mode Exit fullscreen mode

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();
}

Enter fullscreen mode Exit fullscreen mode

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();
    }
  },
)

Enter fullscreen mode Exit fullscreen mode

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(),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

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.
          ],
        ),
      ),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

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,
        ),
      ],
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

Remember to adjust and expand on this code according to your app's specific requirements.

Video: https://youtu.be/otmsUXamIOk (in Hindi)

Top comments (0)