Flutter screen size calculation
Asked Answered
C

2

20

I am getting sick trying to adapt my app to a certain tablet dimensions using flutter.

The tablet is a Samsung Galaxy Tab S5e with screen of 2560x1600.

When I make flutter return the screen dimensions using:

print("Size W is ${MediaQuery.of(context).size.width}");
print("Size H is ${MediaQuery.of(context).size.height}");

What I get is:

Size W is 1137.7777777777778
Size H is 711.1111111111111

Then, from this answer I learned to use:

var pixRatio = MediaQuery.of(context).devicePixelRatio;

So now I can actually get the right value using:

print("Corrected size W is ${MediaQuery.of(context).size.width * pixRatio}");
print("Corrected size H is ${MediaQuery.of(context).size.height * pixRatio}");

And get:

Corrected size W is 2560.0
Corrected size H is 1600.0

The problem is that, every time I want to put a widget with dimension, Container, Image, specify a text size etc on the screen, I have to use the trick like

Container(
    width: 100 / pixRatio,
    height: 200 / pixRatio,
),

If i do not include the /pixRatio correction, it just draws incorrectly and I get lots of pixel overflows..

Is that the only way to put widgets on the screen with the correct size??, I mean, do I really NEED to add every single time the /pixRatio correction on width and height??

Sounds not very practical for me.

Cuirass answered 16/7, 2019 at 7:39 Comment(0)
R
28

The default unit of measure in Flutter is the DIP (density-independent pixel). Different devices have different screen sizes and resolutions, which lead to different pixel ratios. The DIP is meant to allow you to design widgets that are roughly the same size visually, regardless of device.

By dividing all sizes by the pixel ratio, you are converting DIPs to regular pixels. If your widget sizes are defined in regular pixels, you will find that your layout will vary a LOT depending on screen resolution, which is likely not what you want.

Your Container is now configured to be 100 pixels wide and 200 pixels tall, on a tablet with a resolution of 2560x1600. You can fully fit 25 such Containers on a single Row. If you now switch to a tablet with a screen resolution of 1280x800 but the same screen size, your Container will visually be twice as wide and twice as tall, therefore occupying an area that's visually 4 times larger! And only 12 of them will fully fit on a single Row. Is that the behavior you want to achieve?

I strongly recommend that you reconsider the layout that you want to achieve and then find out how to achieve it using the default unit of measure rather than pixels.

If on the other hand you think you have a valid reason for using pixels instead, please mention it in the question so that it can be addressed.

Randarandal answered 16/7, 2019 at 9:38 Comment(2)
thanks for the clear explanation, all makes more sense now, just 2 extra comments to your explanation: 1) Im curious when you say "find out how to achieve it using the default unit of measure" what you mean?, adjust the widget sizes based on DPI so it works on any device? and 2) regarding the last part, yeah, this layout, for certain reasons, is meant to work ONLY on that particular tablet with 2560x1600.Cuirass
1) I don't know what layout you are trying to achieve, but there are lots of different ways to control the sizes of your widgets. One way is to adjust the widget sizes as you've said, but you could also distribute the available space equally or in specific percentages across a number of widgets (see Row, Column, Grid, Expanded, Flexible, etc.), or maybe define minimum and maximum widths and heights using BoxConstraints. The possibilities are endless! 2) This will only make your task easier as you won't need to test or consider other screen sizes and resolutions (would still be good practice)Randarandal
F
1

You can take a look at this package. It allows you to create pixel perfect UI no mater on which device you run your app. https://pub.dev/packages/flutter_screenutil

Funereal answered 21/9, 2021 at 9:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.