flutter_glove_box icon indicating copy to clipboard operation
flutter_glove_box copied to clipboard

Device Pixel Ratio should apply to window and viewport size

Open rayliverified opened this issue 3 years ago • 6 comments

Setting devicePixelRatio does not change the viewport size. So, I'm proposing that the property be applied to the viewport size.

For a Device configuration such as:

static const Device iPhone12ProMax = Device( name: 'iPhone 12 Pro Max', size: Size(1284, 2778), devicePixelRatio: 3);

The actual viewport size is 428 x 926. When this configuration is used however, the viewport is the pixel size which makes the UI too small.

There is also an internal Flutter issues that the team is aware of where Flutter widgets use the window properties instead of the wrapping MaterialApp, hence setting the properties via MediaQueryWrapper does not work. Hence the solution is to divide the screen size by the pixel ratio and use that as the correct viewport.

rayliverified avatar Aug 19 '21 21:08 rayliverified

Any updates on this?

quoc-huynh-cosee avatar Apr 18 '23 07:04 quoc-huynh-cosee

Could you check with version 0.1.5 or later of https://pub.dev/packages/golden_toolkit? @rayliverified is the problem still present?

BenVercammen avatar Apr 18 '23 14:04 BenVercammen

I'm using the version 0.1.5. I'm using MediaQueryData.fromWindow(WidgetsBinding.instance.window).size to determine if the device is a phone or a tablet. But if I use DeviceBuilder with multiple Devices I get wrong sizes.

void main() {
  testGoldens('description', (tester) async {
    final builder = DeviceBuilder()
      ..overrideDevicesForAllScenarios(
        devices: const [
          Device(
            name: 'iPhone SE',
            size: Size(320, 568),
            devicePixelRatio: 2,
          ),
          Device(
            name: 'iPad Pro 6th',
            size: Size(1024, 1366),
            devicePixelRatio: 2,
          ),
        ],
      )
      ..addScenario(widget: const MyWidget());

    await tester.pumpDeviceBuilder(builder);
    await screenMatchesGolden(tester, 'widget');
  });
}

class MyWidget extends StatefulWidget {
  const MyWidget({super.key});

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  void initState() {
    super.initState();
    print(MediaQueryData.fromWindow(WidgetsBinding.instance.window).size); // prints Size(1380.0, 1392.0)
  }

  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

quoc-huynh-cosee avatar Apr 19 '23 08:04 quoc-huynh-cosee

I'm not sure why you are trying to get the size in the initState(), but you are using deprecated methods and you need to have the context available.

When querying in the build method, the sizes are as expected:

class _MyWidgetState extends State<MyWidget> {
  @override
  void initState() {
    super.initState();
    print(MediaQueryData.fromWindow(WidgetsBinding.instance.window).size); // prints Size(1380.0, 1392.0)
  }

  @override
  Widget build(BuildContext context) {
    print('BUILD: ${MediaQuery.sizeOf(context)}');  // retrieve size in build method...
    return const Placeholder();
  }
}

BenVercammen avatar May 01 '23 06:05 BenVercammen

This was just an example. I wanted to retrieve the screen size without BuildContext. I didn't kow the method I used is deprecated. Thanks for your feedback!

quoc-huynh-cosee avatar May 02 '23 06:05 quoc-huynh-cosee

This appears to work for me as of 0.15.0, but was broken in previous versions. The size reported by MediaQuery on 0.14.0 versions was the size passed to device divided by the pixel ratio, and the output PNG size was the size multiplied by the pixel ratio.

In the fixed version the size from MediaQuery is the same as the size passed to device, and the output pixel size is the size passed to device multiplied by the pixel ratio.

maBarabas avatar Jun 27 '23 13:06 maBarabas