Welcome to responsive_screen_size, a package that provides pragmatic responsive-layout utils.

Getting started

You need to add the package responsive_screen_size to your dependencies.

dependencies:
  responsive_screen_size: ^latest # replace latest with version number

Usage

ScreenSizeDispatcher

ScreenSizeDispatcher(
  other: (_, __) => const NormalWidget(),
  smartphone: (_, __) => const SmallWidget(),
),

This widget listens for changes to the display width through MediaQuery. In case the size changes, it will rebuild. This widget is used for responsive layout.

Example: the page scaffold should display a BottomNavigationBar on smartphones, however it should switch to a NavigationRail on tablets.

How to use this widget:

  • It cannot be used before one of MaterialApp(.router), CupertinoApp(.router), ... is added to the widget tree.
  • It does not necessarily have to be used only at the scaffold level: it can also be used down the widget tree; however, in some cases you might favour LayoutBuilder.
  • Internally, it uses MediaQuery to read the dimensions of the screen. Once a breakpoint is reached, e.g., smartphone to tablet, a different widget might be built.

matchScreenSize

matchScreenSize is a declarative pattern to invoke the right function for the matching display size.

One can use this function in combination with virtual_platform or design_language, but you can use it also without.

Pseudocode:

matchDesignLanguage
  material
    matchScreenSize
      smartphone showModalBottomSheet
      other      showSomeSpecialDialog
  cupertino
    matchScreenSize
      smartphone iphoneBottomSheet
      tablet     ipadBottomSheet
      other      desktopBottomSheet

Breakpoints

The developers don't have to specify any breakpoints, since they are already taken care of by this package.

It might be possible that those breakpoints are incorrect on some devices; in those cases please open an issue ;)

To test it you can override breakpoints in your main:

void main() {
  breakPoints = BreakPoints(500, 800, 1300);
  runApp(...);
}

Or you can also implement AbstractBreakPoints yourself if there should be a mismatch among platforms. The following example uses the package physical_platform.

class AdvancedBreakPoints extends AbstractBreakPoints {
  AdvancedBreakPoints(
  ) : super(500, 800, 1300);

  //! In case a platform has way more logical pixels than the other ones,
  //! add the chain of that platform to the [matchPhysicalPlatform] below.

  @override
  bool isSmartphone(double width) => matchPhysicalPlatform(
        other: () => lessThan(width, smartphoneMaxWidth),
        ios: () => lessThan(width, 550), //! maybe pixels differ on iOS?
      );

  @override
  bool isTabletSmall(double width) =>
      matchPhysicalPlatform(other: () => lessThan(width, tabletSmallMaxWidth));

  @override
  bool isTabletLarge(double width) =>
      matchPhysicalPlatform(other: () => lessThan(width, tabletLargeMaxWidth));
}

And then:

void main() {
  breakPoints = AdvancedBreakPoints();
  runApp(...);
}