- Go to
pubspec.yaml - Add awesome_extensions and replace
[version]with the latest version:
dependencies:
awesome_extensions: ^[version]- Click the packages get button or run
flutter pub get
See awesome_extensions for docs & samples
- Awesome Extensions
- Let get started 💪
- See awesome_extensions for docs & samples
- About
- Theme Extensions
- Media Query Extensions For Responsive Layout
- Navigation Extensions
- Widget Extensions
- List Extensions
- Date Extensions
- Number Extensions
- String Extensions
- Async Extensions
- Color Extensions
- Url Strategy
- Avatar Image
- Support
- ❤️❤️❤️
A comprehensive Flutter extension package that helps reduce boilerplate code and adds helpful methods to widgets, enabling you to create responsive designs with ease. This package provides extensions for widgets, themes, navigation, colors, strings, dates, and much more.
From the TextStyle Access properties right in the context instance.
// Before
Text('Hello World', style: Theme.of(context).textTheme.labelSmall),
Text('Hello World', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold, fontSize: 40)),
// After
Text('Hello World', style: context.labelSmall),
// OR
Text('Hello World', style: context.displaySmall),
// If you want to bold text then
Text('Hello World', style: context.labelSmall?.bold),FontWeight extensions that apply font weights on TextStyle:
mostThickorw900The most thick - FontWeight.w900extraBoldorw800Extra-bold - FontWeight.w800boldorw700Bold - FontWeight.bold - FontWeight.w700semiBoldorw600Semi-bold - FontWeight.w600mediumorw500Medium - FontWeight.w500regularorw400Regular - FontWeight.w400lightorw300Light - FontWeight.w300extraLightorw200Extra-light - FontWeight.w200thinorw100Thin, the least thick - FontWeight.w100
Similar 2021 TextStyle are:
context.displayLargecontext.displayMediumcontext.displaySmallcontext.headlineLargecontext.headlineMediumcontext.headlineSmallcontext.titleLargecontext.titleMediumcontext.titleSmallcontext.bodyLargecontext.bodyMediumcontext.bodySmallcontext.labelLargecontext.labelMediumcontext.labelSmall
If you don't want to use theme styles, then we have some other methods:
Text('Hello World')
.bold()
.fontSize(25)
.italic();Similar methods are:
textScale()TextScalebold()Bold Textitalic()Italic TextfontWeight()Specific FontWeightfontSize()Specific FontSizeletterSpacing()Specific LetterSpacingheight()Specific HeightwordSpacing()Specific WordSpacingfontFamily()Specific FontFamilytextShadow()Specific TextShadowtextColor()TextColortextAlignment()Specific TextAlignmentwithUnderLine()TextUnderLine
From the Theme class. Access your themes right in the context instance.
context.themecontext.textThemecontext.primaryTextThemecontext.bottomAppBarThemecontext.bottomSheetThemecontext.appBarThemecontext.backgroundColorcontext.primaryColorcontext.primaryColorLightcontext.primaryColorDarkcontext.focusColorcontext.hoverColorcontext.dividerColorcontext.scaffoldBackgroundColor
From the MediaQuery Access properties right in the context instance.
// Before
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width,
)
// After
Container(
width: context.width,
height: context.width,
)Similar extensions are:
context.height/// Height of the Screen,context.width// Width of Screencontext.mediaQuerySizecontext.orientationcontext.mediaQueryPaddingcontext.alwaysUse24HourFormatcontext.devicePixelRatiocontext.platformBrightnesscontext.textScaleFactorcontext.isLandscapecontext.isPortraitcontext.mediaQueryViewPaddingcontext.mediaQueryViewInsetscontext.mediaQueryShortestSidecontext.showNavbar// True if width be larger than 800context.isPhone// True if the shortestSide is smaller than 600pcontext.isTablet// True if the current device is Tabletcontext.isSmallTablet// True if the shortestSide is largest than 600pcontext.isLargeTablet// True if the shortestSide is largest than 720p
Old Way ❌
MediaQuery.of(context).size;
MediaQuery.of(context).padding;
MediaQuery.of(context).orientation;By calling MediaQuery.of(context).size, the widget will rebuild when any of the MediaQuery properties change (less performant).
New Way ✅
MediaQuery.sizeOf(context);
MediaQuery.paddingOf(context);
MediaQuery.orientationOf(context);By calling MediaQuery.sizeOf(context), the widget will rebuild only when the size changes, avoiding unnecessary rebuilds.
context.mqSize// The same of MediaQuery.sizeOf(context)context.mqHeight// The same of MediaQuery.sizeOf(context).heightcontext.mqWidthcontext.mqPadding// similar to [MediaQuery.paddingOf(context)]context.mqViewPaddingcontext.mqViewInsetscontext.mqOrientationcontext.mqAlwaysUse24HourFormatcontext.mqDevicePixelRatiocontext.mqPlatformBrightnesscontext.mqTextScaleFactor
//Check in what platform the app is running
MyPlatform.isAndroid
MyPlatform.isIOS
MyPlatform.isMacOS
MyPlatform.isWindows
MyPlatform.isLinux
MyPlatform.isFuchsia
//Check the device type
MyPlatform.isMobile
MyPlatform.isDesktop
//All platforms are supported independently in web!
//You can tell if you are running inside a browser
//on Windows, iOS, OSX, Android, etc.
MyPlatform.isWeb
// Returns a value<T> according to the screen size
// can give value for:
// mobile: if the shortestSide is smaller than 600
// tablet: if the shortestSide is smaller than 1200
// desktop: if width is largest than 1200
context.responsiveValue<T>(
T? mobile,
T? tablet,
T? desktop,
),
// Example
Container(
child: context.responsiveValue(
mobile: Container(
color: Colors.yellow,
width: context.width,
height: context.height,
),
tablet: Container(
color: Colors.green,
width: context.width,
height: context.height,
),
desktop: Container(
color: Colors.black,
width: context.width,
height: context.height,
)),
)From the Navigator Access properties right in the context instance.
// Before
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
// After
// for push
context.push(SecondScreen());
context.pushNamed('/home');
// for back , you can also add back result data
context.pop();
// for replace
context.pushReplacement(SecondScreen());
context.pushReplacementNamed('/home');
// popUntil
context.popUntil('/login');
// with rootNavigator
context.push(SecondScreen(), rootNavigator: true);
context.pushReplacement(SecondScreen(), rootNavigator: true);
context.popUntil('/login', rootNavigator: true);
context.routeSettings;
context.routeName;
context.routeArguments;This extension is reduced more code.
// Before
SizedBox(
height : 20.0
)
// After
// make space of 20.0 height
20.0.heightBox
// for width
20.0.widthBox// Before
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("text"),
);
// After
Text("text").paddingAll(8.0),Similar padding extensions are:
paddingAllCreates insets from offsets from all side.paddingOnlyCreates insets with only the given values non-zero.paddingLTRBCreates insets from offsets from the left, top, right, and bottom.paddingSymmetricCreates insets with symmetrical vertical and horizontal offsets.paddingFromWindowPaddingCreates insets that match the given window padding.
// Before
Opacity(
opacity: 0.5,
child: Text("text"),
)
// After
Text("text").setOpacity(0.5)/// Before
Expanded(
child: Text("text"),
)
// After
Text("text").expanded()/// Before
Flexible(
child: Text("text"),
)
// After
Text("text").flexible()Container(height: 50, width: 50).applyShimmer();You can also change the shimmer colors using baseColor and highlightColor parameters:
Container(height: 50, width: 50)
.applyShimmer(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
);Sometimes, according to a condition, we want to display nothing. Usually when we can't return null, we would return something like const SizedBox() for example.
This is good, but it has some performance impacts since SizedBox creates a RenderObject. The RenderObject lives in the render tree and some computations are performed on it, even if it paints nothing on the screen.
We can do better, we can have a widget which does not create a RenderObject, while being still valid. The Nil widget is the minimal implementation for this use case. It only creates an Element and does nothing while it's building. Because the optimal way to use it, is to call const Nil(), it also comes with a nil constant that you can use everywhere (which is a const Nil()).
// Good
text != null ? Text(text) : const Container()
// Better
text != null ? Text(text) : const SizedBox()
// BEST
text != null ? Text(text) : nil
or
if (text != null) Text(text)Text(text).sliver;
// is same as
SliverToBoxAdapter(
child: Text(text),
);Now we can just add round corners, shadows, align, and added gestures to our Widgets.
Container(
height: 100,
width: 100,
)
.withRoundCorners(backgroundColor: Colors.grey)
.withShadow()
.alignAtCenter()
.toCenter()
.withTooltip('My Tooltip')
.paddingOnly(left: 10)
.paddingAll(20)
.onTap(() => print('tap'))
.onLongPress(() => print('long press'));Automatically detect platform and show material and cupertino dialog
context.showAlertDialog(
title: 'title',
message: 'message',
);Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget?>[
Container(
height: 100,
width: 100,
color: Colors.red,
).showIf(true),
Container(
height: 100,
width: 100,
color: Colors.green,
).showIf(false),
].notNullWidget(), // returns only not null widgets
),Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Hello').paddingAll(5),
const Text('World').paddingAll(5),
const Text('Seperated').paddingAll(5),
const Text('By').paddingAll(5),
const Text('Commas').paddingAll(5),
].separatedBy(
const Text(','),
),
),
// for check two date are same or not
date.isSameDate(otherdate); // its return bool (true/false)
// for check date is today's date
date.isToday // its return bool (true/false)
// for check this date is yesterday's date
date.isYesterday // its return bool (true/false)Utility to delay some callback (or code execution).
print('+ wait for 2 seconds');
await 2.delay();
print('- 2 seconds completed');
print('+ callback in 1.2sec');
1.delay(() => print('- 1.2sec callback called'));Easy way to make Durations from numbers.
print(1.seconds + 200.milliseconds);
print(1.hours + 30.minutes);
print(1.5.hours);
5.isLowerThan(4);
5.isGreaterThan(4);
5.isEqual(4);// your name => Your Name
'your name'.capitalize();
// your name => Your name
'your name'.capitalizeFirst();
// your name => yourname
'your name'.removeAllWhitespace();
// Match any RegExp
'test123'.hasMatch(r'[0-9]'); // true
// Return bool if matches pattern
'123'.isNumericOnly(); // true
'abc'.isAlphabetOnly(); // true
'Hello'.hasCapitalLetter(); // true
'true'.isBool(); // trueAn extension to help dealing with all the possible states of an AsyncSnapshot in a StreamBuilder / FutureBuilder.
Reduces boilerplate code significantly by moving each possible state into its own function.
StreamBuilder(
stream: incomingMessagesStream,
builder: (context, snapshot) {
snapshot.when(
data: (data, isComplete) {
return Column(
children: [
Text('Latest Message: $data'),
if (isComplete) Text('No More Message'),
]
);
},
error: (error, stackTrace) {
return Text('We have an error');
},
loading: () {
return CircularProgressIndicator();
},
);
},
);Also you can use maybeWhen, similar to [when], but allows [data] callback to be optional.
The darken method darkens the color by a specified percentage. The percentage should be between 0 and 100. By default, the color is darkened by 10%.
Color darkRed = Colors.red.darken(20); // Darkens the red color by 20%The lighten method lightens the color by a specified percentage. The percentage should be between 0 and 100. By default, the color is lightened by 10%.
Color lightRed = Colors.red.lighten(20); // Lightens the red color by 20%The alphaPercent method sets the alpha transparency using percentage values (0-100).
Color semiTransparent = Colors.blue.alphaPercent(50); // 50% transparency
Color almostOpaque = Colors.red.alphaPercent(90); // 90% opacityAlso added some extra color extensions like: string hex to color, brightness, and change specific RGB color value.
With a simple call of setPathUrlStrategy, your Flutter web app does not have a leading #
in the URL anymore 🚀
void main() {
// Here we set the URL strategy for our web app.
// It is safe to call this function when running on mobile or desktop as well.
setPathUrlStrategy();
runApp(MyApp());
}AvatarImage(
backgroundImage: NetworkImage(
'https://mdbootstrap.com/img/Photos/Avatars/img%20%281%29.jpg',
),
shape: AvatarImageShape.standard,
size: ImageSize.LARGE,
child: Text('Lucky'),
backgroundColor: Colors.red,
),
AvatarImage(
shape: AvatarImageShape.circle,
child: Text('JP'),
backgroundColor: Colors.red,
),| Properties | Description |
|---|---|
| child | type of [Widget], which can have text , icon etc |
| backgroundColor | Color to fill the background of avatar |
| foregroundColor | Color to change the textColor inside the avatar |
| radius | size of the avatar |
| minRadius | minimum size of the avatar |
| maxRadius | maximun size of the avatar |
| size | size of the avatar i.e ImageSize.large, ImageSize.medium, ImageSize.small |
| shape | shape of the avatar i.e, AvatarImageShape.standard, AvatarImageShape.circle, AvatarImageShape.square |
| borderRadius | extra radius to avatar shapes, not applicable to circular avatar |
You liked this package? Then give it a star! If you want to help then:
- ⭐ Star this repository
- 🔧 Send a Pull Request with new features
- 📢 Share this package
- 🐛 Create issues if you find a bug or want to suggest something
Supported by JetBrains Open Source




