Ensure all visual gaps between your widgets are consistent, adapted to the axis direction, and respond to screen size!
Core Features
Provides a Gutter
and Margin
that correspond to Material Design's
Responsive Layout system.
Gutters and margins:
- Create a vertical gap in vertical layouts (
Column
, verticalScrollable
, etc) and a horizontal gap in horizontal layouts (Row
, horizontalScrollable
, etc). - Size the gap according to the current screen size and Material Design's corresponding breakpoint definition (small gap on small screens, larger gap on large screens)
GutterSmall
, GutterTiny
and GutterLarge
all provide gaps that are factors of the base gutter
size for situations where larger or smaller gaps are more appropriate.
For more flexibility, you can also use the provided extension on BuildContext
to reference the
gutter and margin sizes directly (context.gutter
, context.margin
) or create a Gap
with a
manually set size.
You can us Gutter
with other packages using GutterConfiguration
and widgetToAxis
(see example).
Supported Widgets
Flutter Gutter's widgets traverse up the widget tree until they find an ancestor that meets one of the following conditions:
GutterConfiguration.maybeOf(context).customWidgetToAxis(widget)
returns a non-nullAxis
(this is a custom function that lets you extend Flutter Gutter to support arbitrary widgets).widget
is a scrollable with a definedaxis
.widget
has anAxis direction
attribute (for example, Flutter Gutter supports Boxy's widgets automatically).
Note that case 3 means that ANY widget with an axis is supported, however this is a dynamic check
which means that the Dart compiler will not be able to tree shake out any axis
attributes on any
widget. This may increase your app's bundle size by a very small amount.
I have a Github issue against Flutter to add an explicit axis scope to Flutter which would resolve this limitation. If you like using Flutter Gutter and want to see it improved, please upvote the linked issue.
Example
Without flutter_gutter
you have to manually specify the axis direction (by using height
or
width
) and specify size of the gap yourself:
return Column(
children: [
const Text('I hate using sized box.'),
SizedBox(height: 10),
const Text('If only there were a better way...'),
],
);
With flutter_gutter
the Gutter
widget identifies that it's in a vertical layout (Column
) and
automatically creates a vertical gap. It also looks up the screen size and sizes the gap accordingly
so you don't have to specify a gap size manually:
return Column(
children: [
const Text('I hate using sized box.'),
Gutter(),
const Text('And now I don\'t have to!'),
],
);
To use the material break point values directly, use the extension on context
:
return Padding(
padding: EdgeInsets.only(left: context.gutter, right: context.gutterSmall),
child: Text('This is the margin size on this device: ${context.margin}'),
);
To use Gutter
with custom widgets that don't expose an axis
argument, use GutterConfiguration
:
return GutterConfiguration(
data: GutterConfigurationData(
widgetToAxis: (widget) {
if (widget is BoxyFlex) {
// Boxy widgets expose their axes via `BoxyFlex.direction`.
return widget.direction;
}
return null;
},
),
child: MyCustomColumn(
chilren: [
const Text('This widget wasn\'t supported by `Gutter` ).'),
Gutter(),
const Text('But with `GutterConfiguration` I can make Gutter work with any widget!'),
],
),
);
Why not just use the existing Gap package?
Gap and Flutter Gutter are very similar, but Flutter Gutter does a few extra things Gap does not:
- Auto sizes gap spacing according to the Material breakpoints system (see "Core Features" above).
- Detects the axis of ANY widget that exposes an
Axis direction
attribute or getter (see "Supported Widgets" above). - Allows you to add support for arbitrary widgets using
GutterConfiguration
andwidgetToAxis
.
Personally, I especially appreciate feature 1 as it makes it easier for me to add spacing and ensures that spacing and padding in different parts of my app are consistently sized. However, if none of the above features are important to you, you'll likely prefer the Gap package!