207

I've created a new application on Flutter, and I've had problems with the screen sizes when switching between different devices.

I created the application using the Pixel 2XL screen size, and because I've had containers with a child of ListView it's asked me to include a height and width for the container.

So when I switch the device to a new device the container is too long and throws an error.

How can I go about making it so the application is optimized for all screens?

Christopher Moore
  • 15,626
  • 10
  • 42
  • 52
Tom O'Sullivan
  • 3,416
  • 5
  • 15
  • 27
  • 3
    https://github.com/flutter/flutter/wiki/Creating-Responsive-Apps has a few starting points, https://github.com/flutter/flutter/issues/6398, https://stackoverflow.com/questions/49519027/how-to-make-responsive-images-in-flutter – Günter Zöchbauer Mar 29 '18 at 10:20
  • 1
    > I've had containers with child of ListView it's asked me to include a height and width for the container. can you clarify? You can create a list view that simply takes entire space. Can you share your layout? – wasyl Jun 30 '18 at 18:05

13 Answers13

418

You can use:

  • double width = MediaQuery.of(context).size.width;
  • double height = MediaQuery.of(context).size.height;

To get height just of SafeArea (for iOS 11 and above):

  • var padding = MediaQuery.of(context).padding;
  • double newheight = height - padding.top - padding.bottom;
Yash
  • 5,459
  • 3
  • 17
  • 29
108

Getting width is easy but height can be tricky, following are the ways to deal with height

// Full screen width and height
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;

// Height (without SafeArea)
var padding = MediaQuery.of(context).viewPadding;
double height1 = height - padding.top - padding.bottom;

// Height (without status bar)
double height2 = height - padding.top;

// Height (without status and toolbar)
double height3 = height - padding.top - kToolbarHeight;
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
  • 1
    Great! Just what I wanted. Crazy that I left out to calculate the safe area height to draw my views. Was wondering what was going wrong all these while! :D Cheers! – Rohit TP Jan 09 '20 at 09:25
  • 1
    Me the same issue. Many thx man :D –  Oct 16 '21 at 21:35
  • Hey, thank you very much. The reference to context works as long as you call it within the @override Widget build(BuildContext context), but how do I get that information when the widget is initialized? – Uwe.Schneider May 30 '23 at 05:54
75

To clarify and detail the exact solution for future researchers:

Without context:

import 'dart:ui';

var pixelRatio = window.devicePixelRatio;

 //Size in physical pixels
var physicalScreenSize = window.physicalSize;
var physicalWidth = physicalScreenSize.width;
var physicalHeight = physicalScreenSize.height;

//Size in logical pixels
var logicalScreenSize = window.physicalSize / pixelRatio;
var logicalWidth = logicalScreenSize.width;
var logicalHeight = logicalScreenSize.height;

//Padding in physical pixels
var padding = window.padding;

//Safe area paddings in logical pixels
var paddingLeft = window.padding.left / window.devicePixelRatio;
var paddingRight = window.padding.right / window.devicePixelRatio;
var paddingTop = window.padding.top / window.devicePixelRatio;
var paddingBottom = window.padding.bottom / window.devicePixelRatio;

//Safe area in logical pixels
var safeWidth = logicalWidth - paddingLeft - paddingRight;
var safeHeight = logicalHeight - paddingTop - paddingBottom;

With context:

//In logical pixels
var width = MediaQuery.of(context).size.width;
var height = MediaQuery.of(context).size.height;

var padding = MediaQuery.of(context).padding;
var safeHeight = height - padding.top - padding.bottom;

Extra info about physical and logical pixels for the curious: https://blog.specctr.com/pixels-physical-vs-logical-c84710199d62

ertgrull
  • 1,180
  • 9
  • 13
  • Actually, both of these now require context because `window` has been deprecated and docs recommend using `View.of(context)` Nonetheless, this is just what I was looking for. Thanks! – jwehrle Aug 12 '23 at 23:49
36

The below code doesn't return the correct screen size sometimes:

MediaQuery.of(context).size

I tested on SAMSUNG SM-T580, which returns {width: 685.7, height: 1097.1} instead of the real resolution 1920x1080.

Please use:

import 'dart:ui';

window.physicalSize;
Hans Zhang
  • 467
  • 5
  • 5
  • 25
    Looks like `MediaQuery.of(context).size` returns logical pixels. But the same will be used by the other Flutter widgets. So all in all you will get a proportional sizing if that's what you need. If you need the exact pixel value of the device you can do something like this, for instance for width: `MediaQuery.of(context).size.width * MediaQuery.of(context).devicePixelRatio`. I've just written an article on this in case more folks will look for the same: https://medium.com/tagmalogic/widgets-sizes-relative-to-screen-size-in-flutter-using-mediaquery-3f283afc64d6 – Miha Jan 04 '20 at 22:10
  • @Mina, another answer said divide by devicePixelRatio. https://stackoverflow.com/a/63123884/9481613 – mLstudent33 Nov 11 '21 at 01:34
14

Using the following method we can get the device's physical height. Ex. 1080X1920

WidgetsBinding.instance.window.physicalSize.height
WidgetsBinding.instance.window.physicalSize.width
Md Jahirul Islam
  • 211
  • 2
  • 10
  • 9
    While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. [From Review](/review/low-quality-posts/27995553) – double-beep Jan 04 '21 at 09:17
8

MediaQuery.of(context).size.width and MediaQuery.of(context).size.height works great, but every time need to write expressions like width/20 to set specific height width.

I've created a new application on flutter, and I've had problems with the screen sizes when switching between different devices.

Yes, flutter_screenutil plugin available for adapting screen and font size. Let your UI display a reasonable layout on different screen sizes!

Usage:

Add dependency:

Please check the latest version before installation.

dependencies:
  flutter:
    sdk: flutter
  # add flutter_ScreenUtil
  flutter_screenutil: ^0.4.2

Add the following imports to your Dart code:

import 'package:flutter_screenutil/flutter_screenutil.dart';

Initialize and set the fit size and font size to scale according to the system's "font size" accessibility option

//fill in the screen size of the device in the design

//default value : width : 1080px , height:1920px , allowFontScaling:false
ScreenUtil.instance = ScreenUtil()..init(context);

//If the design is based on the size of the iPhone6 ​​(iPhone6 ​​750*1334)
ScreenUtil.instance = ScreenUtil(width: 750, height: 1334)..init(context);

//If you wang to set the font size is scaled according to the system's "font size" assist option
ScreenUtil.instance = ScreenUtil(width: 750, height: 1334, allowFontScaling: true)..init(context);

Use:

//for example:
//rectangle
Container(
           width: ScreenUtil().setWidth(375),
           height: ScreenUtil().setHeight(200),
           ...
            ),

////If you want to display a square:
Container(
           width: ScreenUtil().setWidth(300),
           height: ScreenUtil().setWidth(300),
            ),

Please refer updated documentation for more details

Note: I tested and using this plugin, which really works great with all devices including iPad

Hope this will helps someone

Rahul Mahadik
  • 11,668
  • 6
  • 41
  • 54
  • if you use this plugin, it means you can only define 1 width and height for example if you use the iPhone 6 (iPhone6 ​​750*1334) then you have to use this values but how is that making it responsive across all different iPhones ???? – GY22 Jul 04 '19 at 22:32
  • 1
    you only set your base design based on one screen size. The plugin adapts correctly to different screen sizes – Logemann Nov 18 '19 at 00:11
  • 1
    exactly this is the best way i use so far .. 85% == – Jack Dec 01 '21 at 02:36
3

Hey you can use this class to get Screen Width and Height in percentage

import 'package:flutter/material.dart';
class Responsive{
  static width(double p,BuildContext context)
  {
    return MediaQuery.of(context).size.width*(p/100);
  }
  static height(double p,BuildContext context)
  {
    return MediaQuery.of(context).size.height*(p/100);
  }
}

and to Use like this

Container(height: Responsive.width(100, context), width: Responsive.width(50, context),);
Nikhil Biju
  • 645
  • 7
  • 8
2

Initally I also got stucked in to the issue. Then I got to know that for mobile we get the exact screen height using MediaQuery.of(context).size.height but for web we will not use that approach so i have use window.screen.height from dart.html library then I also added the max screen size that we can use in web by making some calculations...


import 'dart:html';
getViewHeight =>
      window.screen!.height! *
      ((window.screen!.height! -
              kToolbarHeight -
              kBottomNavigationBarHeight -
              120) /
          window.screen!.height!);
kIsWeb
? getViewHeight
: MediaQuery.of(context).size.height * 0.7)

By Using this approach we get max usable screen size dynamically.

1

How to access screen size or pixel density or aspect ratio in flutter ?

We can access screen size and other like pixel density, aspect ration etc. with helps of MediaQuery.

syntex : MediaQuery.of(context).size.height

mewadaarvind
  • 349
  • 3
  • 9
1

Just declare a function

Size screenSize() {
return MediaQuery.of(context).size;
}

Use like below

return Container(
      width: screenSize().width,
      height: screenSize().height,
      child: ...
 )
iOS Lifee
  • 2,091
  • 23
  • 32
1

A bit late as I had asked the question about 2 years ago and was a newbie back then, but thanks all for the responses as at the time when learning it was a massive help.

To clarify, what I probably should have been asking for was a the Expanded widget, as I believe (hazy memory on what I was trying achieve) I was looking to have a ListView as one of the children of a Column. Instead of using the specific screen size to fit this ListView in the Column I should have been looking to optimise the maximum space available, therefore wrapping the ListView in the Expanded would have had the desired impact.

MediaQuery is great, but I try only to use it to decipher what form factor the screen is using the Material breakpoints, otherwise I try to use the Expanded/Spacer widgets as much as possible, with BoxConstaints on minimum/max sizes, also need to consider the maximum space that is actually available using the SafeArea widget to avoid notches/navigation bar,

Tom O'Sullivan
  • 3,416
  • 5
  • 15
  • 27
1
 import 'dart:ui';

 var pixelRatio = window.devicePixelRatio;

 //Size in physical pixels
 var physicalScreenSize = window.physicalSize;`

Very good, problem is that when you build for --release it does not work. The reason is that Size is zero at app start so if the code is fast the value of phisicalSize is (0.0, 0.0).

did you find a solution for this ?

0

I initially grab the size from MediaQuery in case I need it, then set up a Future to run in 500ms to grab it again. It is correct in the second try. My app is a game that starts with a menu so if size is off a little it does not matter.

EJ Thayer
  • 151
  • 2
  • 3