22

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.

Bill P
  • 3,622
  • 10
  • 20
  • 32
Manish Wagle
  • 456
  • 2
  • 5
  • 12

6 Answers6

54

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

kareem alkoul
  • 739
  • 6
  • 13
9

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

Mohammad Khan Awan
  • 164
  • 1
  • 3
  • 8
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,
)
Mohit Shetty
  • 1,551
  • 8
  • 26
0

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;
    }
bk3
  • 41
  • 3
0

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) aswell.

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;
mikyll98
  • 1,195
  • 3
  • 8
  • 29
-4

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)
JISHNU N
  • 9
  • 1
  • 5