연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
Awesome Extensions


Let's get started 💪
- 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
About
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.
Theme Extensions
TextStyle
From the TextStyle Access properties right in the context instance.
Text('Hello World', style: Theme.of(context).textTheme.labelSmall),
Text('Hello World', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold, fontSize: 40)),
Text('Hello World', style: context.labelSmall),
Text('Hello World', style: context.displaySmall),
Text('Hello World', style: context.labelSmall?.bold),
FontWeight extensions that apply font weights on TextStyle:
mostThick or w900 The most thick - FontWeight.w900
extraBold or w800 Extra-bold - FontWeight.w800
bold or w700 Bold - FontWeight.bold - FontWeight.w700
semiBold or w600 Semi-bold - FontWeight.w600
medium or w500 Medium - FontWeight.w500
regular or w400 Regular - FontWeight.w400
light or w300 Light - FontWeight.w300
extraLight or w200 Extra-light - FontWeight.w200
thin or w100 Thin, the least thick - FontWeight.w100
Similar 2021 TextStyle are:
context.displayLarge
context.displayMedium
context.displaySmall
context.headlineLarge
context.headlineMedium
context.headlineSmall
context.titleLarge
context.titleMedium
context.titleSmall
context.bodyLarge
context.bodyMedium
context.bodySmall
context.labelLarge
context.labelMedium
context.labelSmall
Text
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() TextScale
bold() Bold Text
italic() Italic Text
fontWeight() Specific FontWeight
fontSize() Specific FontSize
letterSpacing() Specific LetterSpacing
height() Specific Height
wordSpacing() Specific WordSpacing
fontFamily() Specific FontFamily
textShadow() Specific TextShadow
textColor() TextColor
textAlignment() Specific TextAlignment
withUnderLine() TextUnderLine
Theme
From the Theme class. Access your themes right in the context instance.
context.theme
context.textTheme
context.primaryTextTheme
context.bottomAppBarTheme
context.bottomSheetTheme
context.appBarTheme
context.backgroundColor
context.primaryColor
context.primaryColorLight
context.primaryColorDark
context.focusColor
context.hoverColor
context.dividerColor
context.scaffoldBackgroundColor
Media Query Extensions For Responsive Layout
From the MediaQuery Access properties right in the context instance.
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width,
)
Container(
width: context.width,
height: context.width,
)
Similar extensions are:
context.height /// Height of the Screen,
context.width // Width of Screen
context.mediaQuerySize
context.orientation
context.mediaQueryPadding
context.alwaysUse24HourFormat
context.devicePixelRatio
context.platformBrightness
context.textScaleFactor
context.isLandscape
context.isPortrait
context.mediaQueryViewPadding
context.mediaQueryViewInsets
context.mediaQueryShortestSide
context.showNavbar // True if width be larger than 800
context.isPhone // True if the shortestSide is smaller than 600p
context.isTablet // True if the current device is Tablet
context.isSmallTablet // True if the shortestSide is largest than 600p
context.isLargeTablet // True if the shortestSide is largest than 720p
MediaQuery as Inherited Model
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).height
context.mqWidth
context.mqPadding // similar to [MediaQuery.paddingOf(context)]
context.mqViewPadding
context.mqViewInsets
context.mqOrientation
context.mqAlwaysUse24HourFormat
context.mqDevicePixelRatio
context.mqPlatformBrightness
context.mqTextScaleFactor
MyPlatform.isAndroid
MyPlatform.isIOS
MyPlatform.isMacOS
MyPlatform.isWindows
MyPlatform.isLinux
MyPlatform.isFuchsia
MyPlatform.isMobile
MyPlatform.isDesktop
MyPlatform.isWeb
context.responsiveValue<T>(
T? mobile,
T? tablet,
T? desktop,
),
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,
)),
)
Navigation Extensions
From the Navigator Access properties right in the context instance.
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
context.push(SecondScreen());
context.pushNamed('/home');
context.pop();
context.pushReplacement(SecondScreen());
context.pushReplacementNamed('/home');
context.popUntil('/login');
context.push(SecondScreen(), rootNavigator: true);
context.pushReplacement(SecondScreen(), rootNavigator: true);
context.popUntil('/login', rootNavigator: true);
context.routeSettings;
context.routeName;
context.routeArguments;
Focus & Keyboard Extensions
Easily manage input focus and dismiss the soft keyboard directly from BuildContext.
context.unfocus();
context.hideKeyboard();
context.requestFocus(myFocusNode);
Widget Extensions
This extension reduces boilerplate code significantly.
SizeBox
SizedBox(
height : 20.0
)
20.0.heightBox
20.0.widthBox
Padding
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("text"),
);
Text("text").paddingAll(8.0),
Similar padding extensions are:
paddingAll Creates insets from offsets from all side.
paddingOnly Creates insets with only the given values non-zero.
paddingLTRB Creates insets from offsets from the left, top, right, and bottom.
paddingSymmetric Creates insets with symmetrical vertical and horizontal offsets.
paddingFromWindowPadding Creates insets that match the given window padding.
Margin
Text("Hello").marginAll(16.0);
Text("Hello").marginSymmetric(horizontal: 10.0, vertical: 5.0);
Text("Hello").marginOnly(left: 8.0, top: 4.0);
Text("Hello").marginDirectional(start: 12.0, top: 6.0);
Layout Helpers
Chainable widget wrappers to eliminate nested boilerplate code.
Text("Long Content").scrollable(scrollDirection: Axis.vertical);
Text("Content").safeArea();
Text("Card Content").card(elevation: 4.0);
Image.network("...").clipRRect(borderRadius: BorderRadius.circular(12));
Text("Visible Content").visible(isLoggedIn);
Text("Fitted Text").fittedBox(fit: BoxFit.contain);
Text("Clickable").inkWell(onTap: () => print('tapped'));
Opacity
Opacity(
opacity: 0.5,
child: Text("text"),
)
Text("text").setOpacity(0.5)
Expanded
Expanded(
child: Text("text"),
)
Text("text").expanded()
Flexible
Flexible(
child: Text("text"),
)
Text("text").flexible()
Shimmer Effect

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]!,
);
Nil Widget
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()).
text != null ? Text(text) : const Container()
text != null ? Text(text) : const SizedBox()
text != null ? Text(text) : nil
or
if (text != null) Text(text)
SliverToBoxAdapter
Text(text).sliver;
SliverToBoxAdapter(
child: Text(text),
);
Other
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',
);
List & Iterable Extensions
Safe Element Access & Lookup
final list = [10, 20, 30];
list.getOrNull(0);
list.getOrNull(5);
list.firstWhereOrNull((e) => e > 15);
list.lastWhereOrNull((e) => e < 25);
Chunking & Distinct Filtering
[1, 2, 3, 4, 5].chunked(2);
users.distinctBy((u) => u.id);
notNullWidget
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(),
),
SeparatedBy
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Hello').paddingAll(5),
const Text('World').paddingAll(5),
const Text('Separated').paddingAll(5),
const Text('By').paddingAll(5),
const Text('Commas').paddingAll(5),
].separatedBy(
const Text(','),
),
),
Map Extensions
A comprehensive set of extensions for advanced Map manipulation, ensuring you write less boilerplate and more expressive code.
Safe Access
Avoid null errors with safe access methods that provide default values.
final map = {'name': 'John'};
final age = map.containsKey('age') ? map['age'] : 30;
final age = map.getOrDefault('age', 30);
getOrDefault(key, defaultValue): Returns the value for the given key or the defaultValue if the key is not in the map.
getOrElse(key, function): Returns the value for the given key or computes it from a function if the key is not in the map.
Filtering
Easily filter maps by keys or values.
final scores = {'math': 95, 'science': 88, 'history': 75};
final scienceScores = scores.filterKeys((key) => key.startsWith('s'));
final highScores = scores.filterValues((value) => value > 90);
Transformation & Merging
Transform maps into different formats or merge them safely.
final params = {'user': 'john_doe', 'page': 2};
final query = params.toQueryString();
final map1 = {'a': 1, 'b': 2};
final map2 = {'b': 3, 'c': 4};
final merged = map1.merge(map2);
Nested Operations
Access and manipulate nested map data with ease using dot notation.
final data = {
'user': {
'profile': {
'name': 'Jane Doe'
}
}
};
final name = data.getNested('user.profile.name');
data.setNested('user.profile.age', 28);
Date Extensions
date.isSameDate(otherDate);
date.isToday;
date.isYesterday;
date.isTomorrow;
date.isLeapYear;
date.daysInMonth;
date.startOfDay;
date.endOfDay;
date.addDays(5);
date.subtractDays(2);
DateTime.now().subtract(const Duration(minutes: 5)).timeAgo;
Number Extensions
Formatting & Calculations
1234.5.toCurrency(symbol: '$');
0.75.toPercent();
3.14159.roundToDecimal(2);
Future & Duration
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);
String Extensions
'your name'.capitalize;
'your name'.capitalizeFirst;
'your name'.removeAllWhitespace;
'Hello World!'.toSlug;
'Hello@# World!'.removeSpecialCharacters;
'{"key": "value"}'.isJson;
'123'.isNumericOnly;
'abc'.isAlphabetOnly;
'Hello'.hasCapitalLetter;
'true'.isBool;
Nullable String Extensions
String? text;
text.isNullOrEmpty;
text.isNotNullOrEmpty;
text.orDefault('Guest');
Async Extensions
An 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.
Color Extensions
Darken
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);
Lighten
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);
Alpha Percentage
The alphaPercent method sets the alpha transparency using percentage values (0-100).
Color semiTransparent = Colors.blue.alphaPercent(50);
Color almostOpaque = Colors.red.alphaPercent(90);
Also added some extra color extensions like: string hex to color, brightness, and change specific RGB color value.
Url Strategy
With a simple call of setPathUrlStrategy, your Flutter web app does not have a leading #
in the URL anymore 🚀
void main() {
setPathUrlStrategy();
runApp(MyApp());
}
Avatar Image
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 |
Support
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
