I'm getting height and width of the screen size using Get.context!.height and Get.context!.width. This works perfect in Debug mode. But in the release APK, it's not working at all due to which all the elements based on these are disappearing.
I also tried using MediaQuery but as the height and width are being used inside a class that doesn't have any BuildContext, MediaQuery is not the solution. So I went with Get.context! which works great in debug version. Once I switch to release version, bam, it no longer works.
Here is the code which is not working in release mode but working in debug mode :
class Dimensions {
static double screenHeight = Get.context!.height;
static double screenWidth = Get.context!.width;
static double pageView = screenHeight / 3.08;
static double pageViewContainer = screenHeight / 4.00;
static double pageDetailsContainer = screenHeight / 7.40;
static double imageButtonSectionHeight = screenHeight * 0.195;
}
Try using Get.overlayContext instead of Get.context`.
I'm using Getx also, please if this also didn't work, consider passing the context as a parameter from the constructor of that class or from your method and use the MediaQuery.of(context) instead.
the BuildContext topic is essential, and it can also be problematic if used incorrectly.
I am trying to work on a project that should be run on web, tablet and mobile platforms. I think there are 2 approaches to do this:
1- Create 3 different widgets for each page of the app. For example:
import 'package:flutter/material.dart';
class ResponsiveLayout extends StatelessWidget {
final Widget mobileBody;
final Widget tabletBody;
final Widget desktopBody;
ResponsiveLayout({
required this.mobileBody,
required this.tabletBody,
required this.desktopBody,
});
#override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth < 500) {
return mobileBody;
} else if (constraints.maxWidth < 1100) {
return tabletBody;
} else {
return desktopBody;
}
},
);
}
}
2- Create only one widget for each screen but check the screen size like mediaquery.of(context).size.width whenever I want to show something differently on web than mobile or table.
I don't know there is also a third approach or which approach is better for big application/projects?
You might want to check out this package:
https://pub.dev/packages/sizer
It is very helpful when working for multiple screen sizes.
From their README:
h - Returns a calculated height based on the device
.w - Returns a calculated width based on the device
.sp - Returns a calculated sp based on the device
SizerUtil.orientation - for screen orientation portrait or landscape
SizerUtil.deviceType - for device type mobile or tablet
Basically, these are 2 ways to handle it.
The tradeoffs here are complexity, flexibility, speed of development and consistency:
if you create 3 separate widgets, you might need to spend more time to preserve consistency (copy code changes between widgets) sometimes, but each widget would be more or less simple to understand.
if you use MediaQuery.of(context) and all the changes automatically propagate to all the versions (which might be a good or a bad thing) and it's way more flexible (i.e. you can show/hide/change some parts of the widget at width < 500 and others at width < 1200), but the code might slowly turn into an unreadable mess.
Here's more info in the official doc
iOS native apps auto-scale the whole ui based on device size (width). Is there a similar behaviour with flutter?
I want to design a ui (with font sizes, paddings, etc) for a master device (iphone xs) and scale the whole ui to all other devices.
Wondering if that is possible as i couldn't find any information about it.
Just responsive sizing that needs me to configure breakpoints etc.
I usually obtain device size on Widget build, and then use a fraction of the width and height for each widget: Something like this:
import 'package:flutter/material.dart';
Size deviceSize;
class Welcome extends StatefulWidget {
WelcomeState createState() => WelcomeState();
}
class WelcomeState extends State<Welcome> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
deviceSize = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: color3,
body: Container(
height:deviceSize.height*0.5,
width:deviceSize.width-50.0,
child: Text("Welcome"),
),
);
}
}
Yes, this indeed is possible. All you need is a ratio-scaling approach with which you scale your entire GUI. Check out this ratio-scaling solution given to another SO answer relating to the Flutter UI scaling issue.
It's better to use MediaQuery.of(context).size, because while using external package, you won't be able to maintain the size of widgets on orientation change which might be a big downfall if your application required orientation change for better visual effects:
Widget build(BuildContext context) {
AppBar appBar = AppBar(title: const Text("My Dashboard"));
height = MediaQuery.of(context).size.height -
appBar.preferredSize.height -
MediaQuery.of(context).padding.top; // for responsive adjustment
width = MediaQuery.of(context).size.width; // for responsive adjustment
debugPrint("$height, width: ${MediaQuery.of(context).size.width}");
return Scaffold(appBar: appBar, body: ResponsivePage(height,width));
}
Check out this package:
https://pub.dev/packages/scaled_app
Replace runApp with runAppScaled, the entire UI design will be scaled automatically.
Helpful when you want adapt to different screen sizes quickly
I have a simple flutter setup to get the width of the screen on device with resolution 2960*1440.
However, flutter returns a screen width of 411 when I run the application on resolution 2960*1440. How does flutter calculate width of a device?
class page extends StatelessWidget {
#override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width.toString();
return Container(
child: Text("Height : $height and Width : $width"),
);
}
}
flutter depends on the MediaQuery method to calculate screen size :
MediaQuery.of(context).size.width ;
as per the documentation it returns the number of the "logical pixels" of your screen which each one of them represent several physical pixels by a factor that differs from a device to another, and if you want the actual number of pixels you can use :
MediaQuery.of(context).size.width * MediaQuery.of(context).devicePixelRatio ;
and for the actual pixels of your screen height:
MediaQuery.of(context).size.height * MediaQuery.of(context).devicePixelRatio ;
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?
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;
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;
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
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;
Using the following method we can get the device's physical height.
Ex. 1080X1920
WidgetsBinding.instance.window.physicalSize.height
WidgetsBinding.instance.window.physicalSize.width
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
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),);
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
Just declare a function
Size screenSize() {
return MediaQuery.of(context).size;
}
Use like below
return Container(
width: screenSize().width,
height: screenSize().height,
child: ...
)
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,
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.
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 ?