/flutter_gehry

A Flutter package that provides a way to do a responsive layout. This package uses a mobile-first breakpoint approach.

Primary LanguageDartMIT LicenseMIT

flutter_gehry

A Flutter package that provides a way to do a responsive layout. This package uses a mobile-first breakpoint approach.


Table of content

  1. Usage
  2. Responsive widgets
    1. ResponsiveBuilder
    2. ResponsiveConstrainedBox
    3. ResponsiveDecoratedBox
    4. ResponsiveFlex
    5. ResponsiveFlexible
    6. ResponsiveGridView
    7. ResponsiveListView
    8. ResponsivePadding
    9. ResponsiveSizedBox
    10. ResponsiveText
    11. ResponsiveWidget

Usage

In order to use this package, you must wrap your app with ResponsiveBreakpointsProvider.

Example:

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ResponsiveBreakpointsProvider(
      child: MaterialApp(
        title: "Responsive app",
        home: Text("Home"),
      ),
    );
  }
}

This will provide the different breakpoints to the app. The breakpoints works be minimum window width.

There are 5 breakpoints: xs, sm, md, lg, and xl.

The defaults values for those breakpoints are:

  • xs: 0 (cannot be configured)
  • sm: 640
  • md: 768
  • lg: 1024
  • xl: 1280

These can be changed by passing an instance of ResponsiveBreakpoints to the breakpoints property of ResponsiveBreakpointsProvider.

Widgets that depend on ResponsiveBreakpointsProvider will only be rebuilt when the current breakpoint change, instead of whenever the window size changes.


If you need some arbitrary value depending on the current breakpoint, you can use ResponsiveBreakpointsProvider.of(context).maybePick(...) or ResponsiveBreakpointsProvider.of(context).pick(...). The difference between both is that pick must be provided the xs value, whereas the maybePick will just return null of no data matches the current breakpoint.

For example, if you want as string to change depending on the breakpoint:

const value = ResponsiveBreakpointsProvider.of(context).pick(
  xs: "This string will be returned on the xs and sm breakpoint",
  md: "This string will be returned on the md and lg breakpoint",
  xl: "This string will be returned on the xl breakpoint",
);

Responsive widgets

Multiple widgets are provided by the package. Do you think there is a widget missing? Open an issue and I will look at it!

Responsive widgets all extends BaseResponsiveWidget, which provides the buildResponsive method, that will be called with a BuildContext and the current Breakpoints to build the widget.

Responsive widgets usually takes a data for each breakpoint. This package is mobile-first, meaning that if no data has been provided for the current breakpoint, the data of the next smaller non-null breakpoint will be used.

For example, if the following data is provided to ResponsivePadding:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ResponsivePadding(
      sm: const EdgeInsets.all(12),
      xl: const EdgeInsets.all(32),
      child: const Text("Responsive padding"),
    );
  }
}

In this example, if the current breakpoint is md, since we did not provide an EdgeInsets for the md breakpoint, the value of the sm breakpoint will be used. If we hadn't provided a value for the sm breakpoint, the child would have been used without adding any padding.


ResponsiveBuilder

Same as ResponsiveWidget, but with WidgetBuilder, which is a Widget Function(BuildContext context) instead of a Widget.

Usage:

ResponsiveBuilder(
  xs: (context) => const Text("This will be displayed on xs, sm and md breakpoint"),
  lg: (context) => const Text("This will be displayed on lg and xl breakpoint"),
);

ResponsiveConstrainedBox

This widget is a wrapper around the ConstrainedBox widget.

If no constraints has been provided for the current breakpoint, the child will be directly returned. If the child is also null, a SizedBox.shrink() will be used.

Usage:

ResponsiveConstrainedBox(
  xs: const BoxConstraints.tightFor(width: 100),
  lg: const BoxConstraints.tightFor(width: 200),
  child: const Text("This text will be constrained depending on the breakpoint"),
);

ResponsiveDecoratedBox

This widget is a wrapper around the DecoratedBox widget.

If there is no data for the current breakpoint, the child will be directly returned. If the child is null, a SizedBox.shrink() will be used.

Usage:

ResponsiveDecoratedBox(
  xs: const BoxDecoration(color: Colors.red),
  xs: const BoxDecoration(color: Colors.blue),
  child: const Text("The background color will change depending on the breakpoint"),
);

ResponsiveFlex

This widget is a wrapper around the Flex widget, which is the base widget of both Row and column. This can be used to display a list of widget with a different direction, depending on the current breakpoint.

For each values, this widget takes a BreakpointsData, and falls back to Flex's default values.

Usage:

ResponsiveFlex(
  direction: const BreakpointsData(
    xs: Axis.vertical,
    lg: Axis.horizontal,
  ),
  children: const [
    Text("The children will be displayed vertically (Column) on the xs, sm and md breakpoint"),
    Text("The children will be displayed horizontally (Row) on the lg and xl breakpoint"),
  ],
);

ResponsiveFlexible

This widget is a wrapper around the Flexible widget, and should only be used as the child of a Flex widget.

This widget takes an instance of ResponsiveFlexibleData for each breakpoint. The ResponsiveFlexibleData represents the Flexible widget, and ResponsiveExpandedData, which extends ResponsiveFlexibleData, represents the Expanded widget.

If there is no data for the current breakpoint, a SizedBox.shrink() will be returned.


ResponsiveGridView

This widget is a wrapper around the GridView widget.


ResponsiveListView

This widget is a wrapper around the ListView widget.


ResponsivePadding

This widget is a wrapper around the Padding widget.

This widget takes an instance of EdgeInsets for each breakpoint.

If there is no data for the current breakpoint, the child will be directly returned, without any padding.

Usage:

ResponsivePadding(
  xs: const EdgeInsets.all(8),
  md: const EdgeInsets.all(24),
  lg: const EdgeInsets.all(42),
  child: Text("This text will have more padding the greater the breakpoint is"),
);

ResponsiveSizedBox

This widget is a wrapper around the SizedBox widget.

This widget takes an instance of ResponsiveSizedBoxData for each breakpoint.

If there is no data for the current breakpoint, a SizedBox with no width and no height will be returned.

Usage:

ResponsiveSizedBox(
  xs: const ResponsiveSizedBoxData(height: 20),
  md: const ResponsiveSizedBoxData(height: 32),
  xl: const ResponsiveSizedBoxData(height: 52),
  child: Text("The SizedBox will take more vertical space the greater the breakpoint is"),
);

ResponsiveText

This widget is a wrapper around the Text widget.

Just like the normal Text widget, the first argument must be a String. The rest of the arguments arguments must be provided via the breakpoints with a BreakpointsData. By passing the text argument, of type BreakpointsData<String>, it will override the defaultText passed to the widget for the current breakpoint.

Usage:

const ResponsiveText(
  "This is the text that will be displayed",
  text: BreakpointsData(
    xl: "This text will override the default text on the xl breakpoint",
  ),
  style: BreakpointsData(
    xs: TextStyle(fontSize: 12),
    md: TextStyle(fontSize: 16),
    xl: TextStyle(fontSize: 20),
  ),
);

ResponsiveWidget

This is a simple widget that takes a Widget for each breakpoint and returns the widget for the current breakpoint.

If there is no data for the current breakpoint, a SizedBox.shrink() will be returned.

Usage:

ResponsiveWidget(
  xs: const SizedBox.square(dimension: 12),
  md: const Text("This Text widget will be displayed on the md and lg breakpoint"),
  xl: const Center(
    child: Text("This Text widget will be displayed on the xl breakpoint"),
  ),
);