Coding Studio

Learn & Grow together.

How MediaQuery & LayoutBuilder used in adoptive design in Flutter application?

When to use MediaQuery or LayoutBuilder

MediaQuery.sizeOf(context):
Purpose: To get the overall screen size (width and height).
When to Use:
When you need to know the device’s screen dimensions.
When you want to create layouts that are relative to the screen size (e.g., a widget that takes up 50% of the screen width).
When you need to know the device’s orientation (portrait or landscape).
When you need to know about other device characteristics like text scale factor, padding, etc.
Note: The size returned by MediaQuery is the size of the entire screen, including any system UI elements (like the status bar or navigation bar).
LayoutBuilder:
Purpose: To get the constraints imposed on a widget by its parent.
When to Use:
When you want a widget to adapt its layout based on the space available to it within its parent.
When you need to create responsive layouts that change based on the parent’s size.
When you want to build widgets that can be used in different contexts and adapt to different sizes.
Note: LayoutBuilder doesn’t give you the screen size. It tells you how much space the parent is giving to the widget.
In essence, MediaQuery is about the device, and LayoutBuilder is about the parent-child relationship in the widget tree. They are both powerful tools for creating flexible and responsive Flutter UIs.

Example of MediaQuery

import 'package:flutter/material.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MediaQuery and LayoutBuilder Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}

class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('MediaQuery and LayoutBuilder Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'MediaQuery.sizeOf(context)',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
MediaQueryExample(),
const SizedBox(height: 30),
const Text(
'LayoutBuilder',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
LayoutBuilderExample(),
],
),
),
);
}
}

class MediaQueryExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Get the screen size using MediaQuery.sizeOf(context)
final screenSize = MediaQuery.sizeOf(context);
final screenWidth = screenSize.width;
final screenHeight = screenSize.height;

return Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.blue),
),
child: Column(
children: [
Text('Screen Width: ${screenWidth.toStringAsFixed(2)}'),
Text('Screen Height: ${screenHeight.toStringAsFixed(2)}'),
const SizedBox(height: 10),
Container(
width: screenWidth * 0.8, // 80% of screen width
height: screenHeight * 0.2, // 20% of screen height
color: Colors.blue.withOpacity(0.5),
child: const Center(
child: Text(
'MediaQuery Sized Box',
style: TextStyle(color: Colors.white),
),
),
),
],
),
);
}
}

Explanation

  1. MediaQueryExample Widget:
    MediaQuery.sizeOf(context): This is the key part. It retrieves the Size object representing the dimensions of the screen.
    screenSize.width and screenSize.height: These properties give you the width and height of the screen in logical pixels.
    Container: A Container widget is used to display the screen dimensions and a colored box.
    width: screenWidth * 0.8 and height: screenHeight * 0.2: The colored box’s dimensions are set to 80% of the screen width and 20% of the screen height, demonstrating how you can use MediaQuery to create responsive layouts.
    toStringAsFixed(2): This is used to format the width and height to two decimal places for better readability.

Example of LayoutBuilder

class LayoutBuilderExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final maxWidth = constraints.maxWidth;
final maxHeight = constraints.maxHeight;

return Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.green),
),
child: Column(
children: [
Text('Max Width: ${maxWidth.toStringAsFixed(2)}'),
Text('Max Height: ${maxHeight.toStringAsFixed(2)}'),
const SizedBox(height: 10),
Container(
width: maxWidth * 0.6, // 60% of available width
height: maxHeight > 0 ? maxHeight * 0.5 : 100, // 50% of available height or 100 if maxHeight is 0
color: Colors.green.withOpacity(0.5),
child: const Center(
child: Text(
'LayoutBuilder Sized Box',
style: TextStyle(color: Colors.white),
),
),
),
],
),
);
},
);
}
}

Explanation

LayoutBuilder: This widget’s builder function is called with BoxConstraints.
BoxConstraints constraints: This object provides the maximum width and height available to the LayoutBuilder’s child. It’s important to understand that these are constraints, not the actual size of the screen. The LayoutBuilder’s parent determines these constraints.
constraints.maxWidth and constraints.maxHeight: These properties give you the maximum width and height that the child can occupy.
Container: A Container widget is used to display the constraints and a colored box.
width: maxWidth * 0.6 and height: maxHeight * 0.5: The colored box’s dimensions are set to 60% of the available width and 50% of the available height, demonstrating how you can use LayoutBuilder to create layouts that adapt to their parent’s size.
maxHeight > 0 ? maxHeight * 0.5 : 100: This is a conditional expression that checks if maxHeight is greater than 0. If it is, it calculates 50% of maxHeight. Otherwise, it sets the height to 100. This is a safety check to prevent errors when maxHeight might be 0.

Happy Learning….

Leave a Reply

Your email address will not be published. Required fields are marked *