π A package absorbing all Flutter utility functions, including extension functions and commonly used widgets.
- π Bottom Sheet
- π BuildContext
- π¨ Colors
- π§ Navigation
- π± Widgets
- πΌ RenderObject
- β Size
Show modal bottom sheets using: context.showModalBottomSheet()
.
Also, this package adds a custom FancyBottomSheet
with a drag indicator at the top. You can create one using context.showFancyModalBottomSheet()
.
In Flutter, you often see the pattern <Class>.of(context)
(e.g., Theme.of(context)
). This package adds extension getters on BuildContext
for those classes so you can just say:
Extension | Shortcut for |
---|---|
context.defaultTextStyle |
DefaultTextStyle.of(context) |
context.directionality |
Directionality.of(context) |
context.form |
Form.of(context) |
context.locale |
Localizations.localeOf(context) |
context.materialLocalizations |
MaterialLocalizations.of(context) |
context.mediaQuery |
MediaQuery.of(context) |
context.overlay |
Overlay.of(context) |
context.pageStorage |
PageStorage.of(context) |
context.scaffold |
Scaffold.of(context) |
context.scaffoldOrNull |
Scaffold.of(context, nullOk: true) |
context.textTheme |
Theme.of(context).textTheme |
context.theme |
Theme.of(context) |
Handy extensions on Brightness
:
Extension | Explanation |
---|---|
brightness.isDark |
β brightness == Brightness.dark |
brightness.isLight |
β brightness == Brightness.light |
brightness.opposite |
opposite Brightness |
brightness.color |
Color representing this brightness, i.e.:Β· Colors.white for Brightness.light Β· Colors.black for Brightness.dark |
brightness.contrastColor |
opposite of brightness.color (above) |
isDark
, isLight
, and contrastColor
can also be used on ThemeData
directly.
Handy extensions on Color
:
Extension | Explanation |
---|---|
color.estimatedBrightness |
estimated Brightness based on color 's luminance |
color.isOpaque |
if opacity is 1.0 |
color.alphaBlendOn(Color background) |
resulting Color when drawing color on top of background |
color.withAdditionalOpacity(double opacity) |
applies opacity by multiplying it to the existing opacity |
color.withAdditionalAlpha(int alpha) |
like above, but with an integer alpha |
color.hsl |
β HSLColor.fromColor(color) |
color.hsv |
β HSVColor.fromColor(color) |
And if you can't decide on a color, just use random.nextColor()
, random.nextColorHsl()
or random.nextColorHsv()
!
Convert between alpha and opacity with int.alphaToOpacity
and double.opacityToAlpha
.
Material Design specifies different opacities of white and black colors to use for text of different emphases on colored backgrounds. You can now use the highEmphasisOnColor
, mediumEmphasisOnColor
and disabledOnColor
extension getters on Color
to make your text legible!
There are also getters on ThemeData
for contrast colors on the primary, accent, background, and error colors.
Access your navigation-related information via extension methods:
Extension | Shortcut for |
---|---|
context.navigator |
Navigator.of(context) |
context.rootNavigator |
Navigator.of(this, rootNavigator: true) |
context.modalRoute |
ModalRoute.of(context) |
Push a new route and pop all previous routes (e.g., when signing out the user):
navigator.pushAndRemoveAll(/* new route */);
// Or using a named route:
navigator.pushNamedAndRemoveAll(/* route name */);
Log navigation events to the console:
MaterialApp(
navigatorObservers: [LoggingNavigatorObserver()],
// ...
)
// Prints:
// Navigator: didPush /dashboard β /articles/12345
// Navigator: didPop /dashboard β /articles/12345
Note: This uses the
name
of routes, so it only works with named routes. If you want to handle all your routing declaratively with proper deep links, check out my package π§ flutter_deep_linking :)
Did you ever want to show a progress indicator inside a button? Or were annoyed to conditionally set a Button's onPressed
to disable it? Fear no moreβββblack_hole_flutter has got you covered!
In FancyFab
(a FloatingActionButton
), FancyTextButton
, FancyOutlinedButton
, and FancyElevatedButton
, we introduce some new parameters:
isLoading
: Setting this totrue
shows aCircularProgressIndicator
and disables this button. You can optionally specify aloadingChild
(loadingLabel
onFancyFab
) to show next to the progress indicator.isEnabled
: Settings this tofalse
disables this button, even ifonPressed
is set.
A layout with two different behaviors:
- By default, all children are positioned next to each other with equal widths. This is comparable to a
Row
with all children wrapped inExpanded
. - If the children are too wide to fit in a single line, or one child would become smaller than its reported minimum width, the children get positioned below each other ("wrapped"). This is similar to a
Column
withMainAxisSize.min
.
A layout taking optional left
, center
, and right
children.
It will try to keep center
in the center of itself, even if only one of left
and right
is set or they have different widths.
When writing a custom layout, you might find this extension on ContainerRenderObjectMixin
useful:
Extension | Explanation |
---|---|
containerRenderObjectMixin.children |
Returns all children using firstChild and childAfter |
Extension | Explanation |
---|---|
size.diagonal |
length of the diagonal of a rectangle with this Size |
size.squaredDiagonal |
β size.diagonal * size.diagonal |
size.coerceAtLeast(Size minimum) |
Ensures size is not smaller than minimum in any axis |
size.coerceAtMost(Size maximum) |
Ensures size is not larger than minimum in any axis |