flutter_screen_lock icon indicating copy to clipboard operation
flutter_screen_lock copied to clipboard

Replace MediaQuery size usage

Open clragon opened this issue 3 years ago • 1 comments

Using MediaQuery.of(context).size plus a factor to define the sizes of widgets is undesirable in most situations. There are quite a few problems with it:

  1. First, the size will always be dependent on the entire screen. the ScreenLock widget could be used inside of a nested Navigator or other confinement which does not take up the entire screen. In that case, the buttons and text would have incorret sizes.

  2. Second, no other widgets in flutter ever use this method to size themselves. All inbuilt widgets in flutter use the Physical Pixels as static values to size themselves. Those physical pixels will make sure that the widgets have the same physical size on all devices. This means, if you use MediaQuery to size your widgets, they will look different and strange next to the normal inbuilt flutter widgets.

  3. Lastly, those factor values start to look very bad on large screens (desktop) or very small devices, because of the way the factor works. An example of how this looks on a desktop screen is provided further down.

Therefore, we should not use MediaQuery and a factor to size our widgets.

mediaquery input button sizing on my desktop looks like this: image

with static values (further down) it looks like this: 74335470

in the screenshots it should be obvious that the scaling fails on desktop. notice how the "cancel" text is incredibly small.this is the effect of the second point above. the spacing on the secrets is unreasonable as well.

Both the MediaQuery values and the static ones look fine on my own phone.

One simple solution is to replace all the values with static ones.

The above desktop screenshot uses:

48 for the button config text style 68 for the button default size 12 for the secret spacing

Those sizes look both okayish on my desktop and my phone. More reasonable sizes might be something like 36, 68 and 12. You probably want to adjust them, as I didn't verify the correct ratio.

Another solution, besides the simply static values, is to use a LayoutBuilder widget plus breakpoints. The layoutbuilder widget gives you the constraints that you are in. This means, this would give you the correct sizes for your "screen", even when inside of a nested navigator or otherwise not a fullscreen.

Then, because factors are not desirable, we can use breakpoints that map to static values. The material design specification talks about what breakpoints they use to decide the different layouts here.

There are packages that provide these breakpoints though I would not add a dependency when not necessary. Regardless, they show a nice example of how these breakpoints could be implemented.

The package uses MediaQuery in these places:

When testing these changes, I used the Windows build of the example folder. It currently doesnt have a Windows part here in github, but you create it by:

  • enabling windows (or other OS) desktop support: flutter config --enable-windows-desktop (found under flutter config -h)
  • running flutter create example again in the folder above example
  • executing the windows build flutter run -d windows

I think it would make this package even better if one of those solutions was implemented and MediaQuery was removed. I tried to be very detailed about my explanation why MediaQuery is a problem. Please let me know if you have questions.

I will probably not make a pull request for this, because I would like you to decide on these important things.

clragon avatar May 18 '22 12:05 clragon

Thanks for the great suggestions. When we first created this package, it was for smartphones, so we did not have a large screen in mind. Hopefully it will be responsive and display properly. I will get some time to consider the response.

naoki0719 avatar May 19 '22 12:05 naoki0719