Getting screen size in a class without buildcontext in Flutter
Asked Answered
C

8

25

I am trying to get screen size in flutter inside a custom class which donot have build method in it. How can i get screen size without using buildcontext class?

The following code :

class ShapesPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {

    BuildContext context;
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;
    final paint = Paint();

    paint.color = Colors.deepOrange;

    var center = Offset(size.width / 2, size.height / 2);

    print(height);
    print(width);

    Rect rect = Rect.fromLTWH(0.0, 0.0, width, height);
    canvas.drawRect(rect, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

gives following error :

The following assertion was thrown during paint(): 'package:flutter/src/widgets/media_query.dart': Failed assertion: line 689 pos 12: 'context != null': is not true.

Cohl answered 2/9, 2019 at 10:15 Comment(0)
O
59

use

MediaQueryData.fromWindow(WidgetsBinding.instance.window);

you can use it to get MediaQuery without need context it depend on instance of window to get size information

Opener answered 25/8, 2021 at 10:22 Comment(8)
This is the only answer on this page that actually answers the original question and is correct.Kunkle
An expression whose value can be 'null' must be null-checked before it can be dereferenced. This is the error I'm getting on using this, can anyone help!Legislature
@Apoorvpandey just add an exclamation mark to it and tell the compiler that you know what you're doing like this MediaQueryData.fromWindow(WidgetsBinding.instance!.window)Tsana
Wow, very nice. I access my height with: MediaQueryData.fromWindow(WidgetsBinding.instance.window).size.width.toInt(). Thanks!Moralize
So you access height with width..?Ticknor
It works, but once I change the orientation, for ex. from Portrait to landscape, it is not updated.Acquittal
'MediaQueryData.fromWindow' is deprecated and shouldn't be used. Use MediaQueryData.fromView instead.Kermanshah
Going by screen size doesn't work on Android as phones like pixel 5, etc. have greater than 600 short size. I haven't found a solid answer for android!Blowsy
V
26

As of May 2023, in Flutter 3.10.1 MediaQueryData.fromWindow() has been deprecated. Use WidgetsBinding.instance.platformDispatcher.views.first.physicalSize.width now. Replace width with height to get the height of the screen

Vincenz answered 24/5, 2023 at 6:8 Comment(1)
On desktop, this will return the physical size of the window, not the size of the screen.Albert
S
5

You can directly pass the screen's width and height as a parameter for the widget ShapesPainter if that is all what you need.

Solution Code:

class ShapesPainter extends CustomPainter {

  final double width;
  final double height;

  ShapesPainter({this.width,this.height});

  @override
  void paint(Canvas canvas, Size size) {

    final paint = Paint();

    paint.color = Colors.deepOrange;

    var center = Offset(size.width / 2, size.height / 2);

    print(height);
    print(width);

    Rect rect = Rect.fromLTWH(0.0, 0.0, width, height);
    canvas.drawRect(rect, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

Usage:

// Wherever you'll be using it
ShapesPainter(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
)
Springwood answered 2/9, 2019 at 10:53 Comment(1)
You can even use double.infinity if you wish to.Springwood
C
4

To complete @MohammadKhanAwan response,

WidgetsBinding.instance.platformDispatcher.views.first.physicalSize.width return the resolution (ex: 1080 / 2400) to get the same value as MediaQuery.of(context).size

you have to divided it by pixel ratio like below

mixin Responsive {
  final double widthScreen = WidgetsBinding
          .instance.platformDispatcher.views.first.physicalSize.width /
      WidgetsBinding.instance.platformDispatcher.views.first.devicePixelRatio;
  
final double heightScreen = WidgetsBinding
              .instance.platformDispatcher.views.first.physicalSize.height /
          WidgetsBinding.instance.platformDispatcher.views.first.devicePixelRatio;
    }

I wrapped the values in a mixin to easily access them from any class or Widget.

Collayer answered 10/6, 2023 at 15:12 Comment(0)
A
2

I previously used window singleton to retrieve the screen width and height:

double width = (window.physicalSize.shortestSide / window.devicePixelRatio);
double height = (window.physicalSize.longestSide / window.devicePixelRatio);

but it was deprecated, and consequently also MediaQueryData.fromWindow() (from the accepted answer) as well.

Solution

FlutterView.physicalSize gives you

The dimensions of the rectangle into which the scene rendered in this view will be drawn on the screen, in physical pixels.

FlutterView.devicePixelRatio gives you

The number of device pixels for each logical pixel for the screen this view is displayed on.

By using the following snippet, you can then obtain the actual logical screen width and height:

FlutterView view = PlatformDispatcher.instance.views.first;

double physicalWidth = view.physicalSize.width;
double physicalHeight = view.physicalSize.height;

double devicePixelRatio = view.devicePixelRatio;

double screenWidth = physicalWidth / devicePixelRatio;
double screenHeight = physicalHeight / devicePixelRatio;
Anchusin answered 14/7, 2023 at 22:20 Comment(0)
M
1

Old

MediaQueryData.fromView(WidgetsBinding.instance.window).size.width

Flutter 3.10.1+

WidgetsBinding.instance.platformDispatcher.views.first.display.size.width / WidgetsBinding.instance.platformDispatcher.views.first.display.devicePixelRatio
Maryland answered 26/4 at 10:53 Comment(0)
K
0

By using the following snippet, you can then obtain the actual logical screen width and height:

import 'dart:ui';

....

FlutterView view = PlatformDispatcher.instance.views.first;
screenWidth = view.physicalSize.width / view.devicePixelRatio;
screenHeight = view.physicalSize.height / view.devicePixelRatio;
Kazan answered 2/5 at 10:20 Comment(1)
In release mode, view.physicalSize.width return 0.0 . You should use views.display.size.widthAilurophobe
M
-5

In the following way, you can get the device screen size without declaring them in the build method.

  void paint(BuildContext context)
{
  double width = MediaQuery.of(context).size.width;
  double height = MediaQuery.of(context).size.height;
}

And you can access them inside other file build methods after importing this method.

paint(context)
Masefield answered 21/5, 2021 at 19:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.