Show some love and like to support the project
Say Thanks Here
Follow Me on Twitter
Platform Support
Android | iOS | MacOS | Web | Linux | Windows |
---|---|---|---|---|---|
✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
Installation
Add this package to pubspec.yaml
as follows:
$ flutter pub add itq_utils
Import package
import 'package:itq_utils/itq_utils.dart';
Initialize itq_utils in main.dart file for initializing Shared Preferences and other variables. Also you can assign your Chat GPT key here.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await initialize();
chatGPTAPIkey = "YOUR_KEY";
runApp(MyApp());
}
Now, add navigatorKey in your MaterialApp or CupertinoApp
return MaterialApp(
debugShowCheckedModeBanner: false,
navigatorKey: navigatorKey,
home: HomePage(),
);
Featured on Google's Dev Library
Contents
- Useful Methods
- Use of TextStyle
- Shared Preference Example
- MaterialYou Theme
- Decorations
- Widgets
- Extensions
- System Methods
- Network Utils
- JWT Decoder
- Dialog
- Custom Dialogs
- Local Notification Service
Useful methods or extensions you will ever need
/// Open a new screen
HomePage().launch(context);
/// Animate the new page (Slide, Rotate, Scale, Fade)
HomePage().launch(context, pageRouteAnimation: PageRouteAnimation.Slide);
/// Remove all screens from back stack and opens new screen
HomePage().launch(context, isNewTask: true);
// Returns to previous Screen
finish(context);
// Returns to previous Screen with a result
finish(context, object);
/// Toast a String
toast('This is a string');
/// Prints only if in debug or profile mode - (parameter is Object)
log('Your string');
void hideKeyboard(context)
/// If you are opening Dialog in initState method and you want to use BuildContext but yet it is not created,
/// You can use afterBuildLayout in initState method like this.
afterBuildLayout(() {
// Get Callback after your build widget is rendered
});
/// Get Package Name from Native Platform (Android, iOS)
await getPackageName();
/// Get Package Name, Version Code, Version Name (Android, iOS)
await getPackageInfo();
/// Return true if Android OS version is above 12
Future<bool> isAndroid12Above()
/// Handle error and loading widget when using FutureBuilder or StreamBuilder
/// "snap" is the snapShot value we get from FutureBuilder or StreamBuilder
return snapWidgetHelper(snap);
/// See the example below. You can Use FutureBuilder or StreamBuilder.
FutureBuilder(
builder(_, snap) {
if (snap.hasData) {
return YourWidget();
} else {
/// This function will handle loading and error automatically.
/// You can modify loading and error widget in parameters.
return snapWidgetHelper(snap);
}
}
),
// Basic SnackBar
snackBar(context, title: 'Sample toast'),
// Enhanced
snackBar(
context,
title: 'Sample toast',
textColor: Colors.blue,
backgroundColor: Colors.white,
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: radius(30)),
margin: EdgeInsets.all(16),
duration: 3.seconds,
);
TextStyles
/// Apply Bold TextStyle
Text(item.title.validate(), style: boldTextStyle()),
/// Apply Primary TextStyle
Text(item.title.validate(), style: primaryTextStyle()),
/// Apply Secondary TextStyle
Text(item.title.validate(), style: secondaryTextStyle()),
Shared Preference Example
/// To use SharedPreference, you must call initialize() method in main.dart file as mentioned in Installations section
/// setValue method has (String key, dynamic value) parameters
/// add a Double in SharedPref
await setValue("key", 20.0);
/// add a bool in SharedPref
await setValue("key", false);
/// add a int in SharedPref
await setValue("key", 10);
/// add a String in SharedPref
await setValue("key", "value");
/// add a String List in SharedPref
await setValue("key", ['value', 'value', 'value']);
/// Returns a Bool if exists in SharedPref
/// You can set a default value if it returns null
getBoolAsync("key");
/// Returns a Double if exists in SharedPref
getDoubleAsync("key");
/// Returns a Int if exists in SharedPref
getIntAsync("key");
/// Returns a String if exists in SharedPref
getStringAsync("key");
/// Returns a JSON if exists in SharedPref
getJSONAsync("key");
/// Remove a key from SharedPref
await removeKey("key");
/// Returns List of Keys that matches with given Key
getMatchingSharedPrefKeys('key')
MaterialYou Theme
Future<dynamic> getMaterialYouColors()
Future<Color> getMaterialYouPrimaryColor()
Decorations
BorderRadius radius([double? radius])
Radius radiusCircular([double? radius])
BorderRadius radiusOnly({double? topRight,double? topLeft,double? bottomRight,double? bottomLeft,})
ShapeBorder dialogShape([double? borderRadius])
/// Apply default BoxDecoration with default shadow and border radius
Container(
decoration: boxDecorationDefault(), // You can modify based on your preference
),
InputDecoration defaultInputDecoration({String? hint, String? label, TextStyle? textStyle})
Widgets
/// Give Blur effect to any widget
/// Use Blur widget to know more properies
Blur(
child: AnyWidget(),
)
/// Making an app for Web? You must have to perform something on mouse hover event.
/// Use HoverWidget to get your widget is being hovering or not
HoverWidget(
builder: (_, isHovering) {
return AnyWidget();
},
),
/// Wrap MaterialApp Widget with RestartAppWidget
/// Use: RestartAppWidget.init(context);
/// Call above line any where to restart your Flutter app.
RestartAppWidget(
child: MaterialApp(),
)
DoublePressBackWidget(
child: AnyWidget(),
message: 'Your message' // Optional
),
/// Add a Google Logo
/// Add size parameter for custom size - Default is 24
GoogleLogoWidget(),
/// You can use your preferred State Management technique
Loader().visible(mIsLoading),
/// Read More Text Widget
/// Use ReadMoreText Widget in your project to get more familiar with other properties
ReadMoreText(
'Long Text',
),
/// Timer widget
TimerWidget(
function: () {
// Do something
},
child: Text('Your Widget'),
duration: 10.seconds,
),
SettingSection(
title: Text('Account Management', style: boldTextStyle(size: 24)),
subTitle: Text('Control your account', style: primaryTextStyle()), // Optional
items: [
SettingItemWidget(
title: 'Hibernate account',
subTitle: 'Temporary deactivate your account',
decoration: BoxDecoration(borderRadius: radius()),
trailing: Icon(Icons.keyboard_arrow_right_rounded, color: context.dividerColor),
onTap: () {
//
}
),
SettingItemWidget(
title: 'Close account',
subTitle: 'Learn about your options, and close your account if you wish',
decoration: BoxDecoration(borderRadius: radius()),
trailing: Icon(Icons.keyboard_arrow_right_rounded, color: context.dividerColor),
onTap: () {
//
},
)
],
),
//SettingItem
SettingItemWidget(
title: "Title",
onTap: () {
//Your Logic
},
trailing: Icon(Icons.home_sharp), // Optional
leading: Icon(Icons.arrow_forward_ios_rounded), // Optional
subTitle: "Subtitle", // Optional
),
/// Default AppButton
/// Use AppButton on your app to try more properties
AppButton(
text: "Submit",
color: Colors.green, // Optional
onTap: () {
//Your logic
},
),
/// Use PlaceHolderWidget while your network image is loading
PlaceHolderWidget(),
/// Use GradientBorder while your network image is loading
GradientBorder(
gradient: LinearGradient(
colors: [
Colors.orange,
Colors.yellow,
Colors.pink,
],
),
strokeWidth: 4.0,
child: AnyWidget(),
)
/// Use RoundedCheckBox widget to get nicely rounded check box
/// It has many optional parameters to get personalized check box widget
RoundedCheckBox(
isChecked: true,
text: 'Remember me',
onTap: (val) {
//
},
),
/// Use SizeListener widget to get callback when its child widget size changes
SizeListener(
child: AnyWidget(),
onSizeChange: (size) {
log(size.width.toString());
},
),
UL(
symbolType: SymbolType.Numbered,
children: [
Text('Hi', style: primaryTextStyle()),
Text('Hello', style: primaryTextStyle()),
Text('How are you?', style: primaryTextStyle()),
],
),
/// Use AppTextField on your app to try more properties
/// Use Form Validate to validate all AppTextField
/// Inbuilt Email Validator, Automatic email keyboard type
AppTextField(
controller: TextEditingController(), // Optional
textFieldType: TextFieldType.EMAIL,
decoration: InputDecoration(labelText: 'Email', border: OutlineInputBorder()),
),
/// Default Min Lines 4
AppTextField(
controller: TextEditingController(), // Optional
textFieldType: TextFieldType.MULTILINE,
decoration: InputDecoration(labelText: 'Address', border: OutlineInputBorder()),
),
/// Automatic password obscure, Show/Hide Password Option
AppTextField(
controller: TextEditingController(), // Optional
textFieldType: TextFieldType.PASSWORD,
decoration: InputDecoration(labelText: 'Password', border: OutlineInputBorder()),
),
/// Add read more button to a long text
ReadMoreText(
'Long Text',
),
/// Build Horizontal List widget without giving specific height to it.
HorizontalList(
itemBuilder: (BuildContext context, int index) {
return AnyWidget();
},
itemCount: 25,
),
RatingBarWidget(
rating: initialRating,
onRatingChanged: (aRating) {
rating = aRating;
},
),
/// Make your Flutter App Responsive in any device out there with Responsive widget
Responsive(
mobile: MobileWidget(),
tablet: TabletWidget(), // Optional
web: WebWidget(), // Optional
),
TextIcon(
text: 'Your text',
prefix: AnyWidget(), // Optional
suffix: AnyWidget(), // Optional
),
DotIndicator(
pageController: pageController,
pages: list,
),
/// Use SnapHelperWidget to handle loading and error widget automatically
/// Still you can specify custom Loader Widget and Error Widget
SnapHelperWidget<T>(
future: future,
onSuccess: (data) {
return AnyWidget();
},
),
DottedBorderWidget(
child: Container(
height: 100,
width: 100,
),
),
Marquee(
direction: Axis.horizontal,
animationDuration: Duration(milliseconds: 100),
pauseDuration: Duration(milliseconds: 100),
child: Text("Please enter a long text to see the effect of the marquee widget"),
),
Extensions
String Extensions
String validate({String value = ''})
bool validateEmail()
bool validatePhone()
bool validateURL()
bool isDigit()
bool isAlpha()
bool isJson()
bool get isInt
bool get isImage
bool get isAudio
bool get isVideo
bool get isTxt
bool get isDoc
bool get isExcel
bool get isPPT
bool get isApk
bool get isPdf
bool get isHtml
String get reverse
Future<void> copyToClipboard()
String capitalizeFirstLetter()
String repeat(int n, {String separator = ''})
String formatNumberWithComma({String seperator = ','})
String toYouTubeId({bool trimWhitespaces = true})
String getYouTubeThumbnail()
String removeAllWhiteSpace()
String getNumericOnly({bool aFirstWordOnly = false})
String toSlug({String delimiter = '_'})
Color toColor({Color? defaultColor})
List<String> toList()
List<String> setSearchParam()
int toInt({int defaultValue = 0})
int countWords()
double toDouble({double defaultValue = 0.0})
double calculateReadTime({int wordsPerMinute = 200})
bool Extensions
bool validate({bool value = false})
int getIntBool({bool value = false})
Color Extensions
String toHex({bool leadingHashSign = true, bool includeAlpha = false})
bool isDark()
bool isLight()
double getBrightness()
double getLuminance()
BuildContext Extensions
Size size()
/// return screen width
double screenWidth()
/// return screen height
double screenHeight()
double pixelRatio()
Brightness platformBrightness()
double get statusBarHeight
double get navigationBarHeight
ThemeData get theme
TextTheme get textTheme
DefaultTextStyle get defaultTextStyle
FormState? get formState
ScaffoldState get scaffoldState
OverlayState? get overlayState
Color get primaryColor
Color get accentColor
Color get scaffoldBackgroundColor
Color get cardColor
Color get dividerColor
Color get iconColor
void requestFocus(FocusNode focus)
bool isPhone()
bool isTablet()
bool isDesktop()
DateTime Extensions - Utils
/// You can use .timeAgo on a DateTime object like this
String result = DateTime.now().timeAgo;
bool get isToday
bool get isYesterday
bool get isTomorrow
/// return current time in milliseconds
int currentMillisecondsTimeStamp()
/// return current timestamp
int currentTimeStamp()
bool leapYear(int year)
/// returns how much time ago from timestamp
String formatTime(int timestamp)
/// returns number of days in given month
int daysInMonth(int monthNum, int year)
Device Extensions
DeviceSize get device
bool get isWeb
bool get isMobile
bool get isDesktop
bool get isApple
bool get isGoogle
bool get isAndroid
bool get isIOS
bool get isMacOS
bool get isLinux
bool get isWindows
String get operatingSystemName
String get operatingSystemVersion
Double Extensions
double validate({double value = 0.0})
bool isBetween(num first, num second)
Size get size
Duration Extensions
/// await Duration(seconds: 1).delay();
Future<void> get delay
int Extensions
/// Validate given int is not null and returns given value if null.
int validate({int value = 0})
/// Leaves given height of space ex: 16.height,
Widget get height
/// Leaves given width of space ex: 16.width,
Widget get width
/// HTTP status code
bool isSuccessful()
BorderRadius borderRadius([double? val])
/// Returns microseconds duration
/// 5.microseconds
Duration get microseconds
Duration get milliseconds
Duration get seconds
Duration get minutes
Duration get hours
Duration get days
bool isBetween(num first, num second)
Size get size
// return suffix (th,st,nd,rd) of the given month day number
String toMonthDaySuffix()
// returns month name from the given int
String toMonthName({bool isHalfName = false})
// returns WeekDay from the given int
String toWeekDay({bool isHalfName = false})
List Extensions
/// Validate given List is not null and returns blank list if null.
List<T> validate()
/// Generate forEach but gives index for each element
void forEachIndexed(void action(T element, int index))
int sumBy(int Function(T) selector)
double sumByDouble(num Function(T) selector)
double? averageBy(num Function(T) selector)
num Extensions
/// Validate given double is not null and returns given value if null.
num validate({num value = 0})
/// Returns price with currency
String toCurrencyAmount()
ScrollController Extensions
ScrollController scrollController = ScrollController();
/// animate to top
scrollController.animToTop();
/// animate to Bottom
scrollController.animToBottom();
/// animate to specific position
scrollController.animateToPosition(20.0);
/// jump to the start of the list without animation
scrollController.jumpToTop();
/// jump to the end of the list without animation
scrollController.jumpToBottom();
Widget Extensions
Widget onTap(Function? function, {BorderRadius? borderRadius, Color? splashColor,Color? hoverColor, Color? highlightColor})
Future<T?> launch<T>(BuildContext context,{bool isNewTask = false, PageRouteAnimation? pageRouteAnimation,Duration? duration})
Widget expand({flex = 1})
Widget flexible({flex = 1, FlexFit? fit})
Widget fit({BoxFit? fit, AlignmentGeometry? alignment})
Widget withTooltip({required String msg})
Widget center({double? heightFactor, double? widthFactor})
Widget visible(bool visible, {Widget? defaultWidget})
SizedBox withSize({double width = 0.0, double height = 0.0})
SizedBox withWidth(double width)
SizedBox withHeight(double height)
Padding paddingTop(double top)
Padding paddingLeft(double left)
Padding paddingRight(double right)
Padding paddingBottom(double bottom
Padding paddingAll(double padding)
Padding paddingOnly({double top = 0.0,double left = 0.0,double bottom = 0.0,double right = 0.0})
Padding paddingSymmetric({double vertical = 0.0, double horizontal = 0.0})
/// Make Image Circular with these extension
ClipRRect cornerRadiusWithClipRRectOnly({int bottomLeft = 0,int bottomRight = 0,int topLeft = 0,int topRight = 0})
ClipRRect cornerRadiusWithClipRRect(double radius)
Widget opacity({required double opacity,int durationInSecond = 1,Duration? duration})
Widget rotate({required double angle,bool transformHitTests = true,Offset? origin})
Widget scale({required double scale,Offset? origin,AlignmentGeometry? alignment,bool transformHitTests = true})
Widget translate({required Offset offset,bool transformHitTests = true,Key? key})
Systems Methods
/// Change status bar Color and Brightness
setStatusBarColor(Colors.blue);
setDarkStatusBar();
setLightStatusBar();
/// Show Status Bar
showStatusBar();
/// Hide Status Bar
hideStatusBar();
/// Set orientation to portrait
setOrientationPortrait();
/// Set orientation to landscape
setOrientationLandscape();
/// Get current PlatformName as a String
String platformName();
/// Enter FullScreen Mode (Hides Status Bar and Navigation Bar)
enterFullScreen();
/// Unset Full Screen to normal state (Now Status Bar and Navigation Bar Are Visible)
exitFullScreen();
/// Returns a string from Clipboard
Future<String> paste();
/// Invoke Native method and get result
var data = await invokeNativeMethod(CHANNEL_NAME, METHOD_NAME, [dynamic arguments]);
Network Utils
Future<bool> isNetworkAvailable()
Future<bool> isConnectedToMobile()
Future<bool> isConnectedToWiFi()
JWT Decoder
/// Pass your token here to get Map<String, dynamic>
Map<String, dynamic> JwtDecoder.decode(token);
bool JwtDecoder.isExpired(token);
DateTime JwtDecoder.getExpirationDate(token);
Duration JwtDecoder.getTokenTime(token);
Duration JwtDecoder.getRemainingTime(token);
Local notification services
/// Pass your audio file 'notification_music.mp3' in res/raw folder and 'app_icon.png' in res/drawable folder inside android/app/src/main then implement below code where you need local notification
late NotificationService _notificationService;
// Create a custom notification configuration (optional)
final NotificationConfig _customConfig = NotificationConfig(
androidAppIcon: 'app_icon', // Custom app icon
assetAppIcon: 'icons/app_icon.png', // Custom asset app icon
androidChannelId: 'my_app_channel',
androidChannelName: 'My App Notifications',
androidChannelDescription: 'Notifications for my awesome app',
notificationSoundResource: 'notification_sound', // Custom sound
);
@override
void initState() {
super.initState();
_initializeNotifications();
}
Future<void> _initializeNotifications() async {
// Initialize notification service with custom config and handlers
_notificationService = NotificationService(config: _customConfig)
..initialize(
onNotificationTap: _handleNotificationTap,
onForegroundMessage: _handleForegroundMessage,
onMessageOpenedApp: _handleMessageOpenedApp,
);
// Check if notifications are enabled
_notificationsEnabled = _notificationService.isNotificationPermissionGranted;
// Get FCM token
_fcmToken = _notificationService.fcmToken;
setState(() {});
}
// Handle local notification tap
void _handleNotificationTap(NotificationResponse response) {
if (kDebugMode) {
print('Notification tapped');
print('Payload: ${response.payload}');
print('Action ID: ${response.actionId}');
}
if (response.payload != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationDetailsPage(
payload: response.payload!,
),
),
);
}
}
// Handle FCM foreground message
void _handleForegroundMessage(RemoteMessage message) {
if (kDebugMode) {
print('Received foreground message:');
print('Title: ${message.notification?.title}');
print('Body: ${message.notification?.body}');
print('Data: ${message.data}');
}
}
// Handle FCM message when app is opened from notification
void _handleMessageOpenedApp(RemoteMessage message) {
if (kDebugMode) {
print('App opened from notification:');
print('Title: ${message.notification?.title}');
print('Body: ${message.notification?.body}');
print('Data: ${message.data}');
}
// Navigate based on the message data
if (message.data['screen'] != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationDetailsPage(
payload: message.data.toString(),
),
),
);
}
}
// Subscribe to FCM topic
Future<void> _subscribeToTopic(String topic) async {
await _notificationService.subscribeToTopic(topic);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Subscribed to topic: $topic')),
);
}
// Unsubscribe from FCM topic
Future<void> _unsubscribeFromTopic(String topic) async {
await _notificationService.unsubscribeFromTopic(topic);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Unsubscribed from topic: $topic')),
);
}
// Example of a notification with Android actions
Future<void> showNotificationWithActions() async {
// Create a notification config with Android actions
final config = NotificationConfig(
androidActionCategories: [
const NotificationCategory(
identifier: 'custom_android_category',
actions: [
NotificationAction(
id: 'custom_action_1',
title: 'Custom Action 1',
iconPath: 'icons/coworker.png'
),
NotificationAction(
id: 'custom_action_2',
title: 'Custom Action 2',
iconPath: 'icons/coworker.png'
),
],
),
],
);
// Initialize the NotificationService with this config
final notificationService = NotificationService(config: config);
// Explicitly process actions
await notificationService.initialize();
// Show the notification with actions
notificationService.showNotification(
title: 'Interactive Notification',
body: 'This notification has multiple actions',
// Optional: Add extra customization
color: Colors.blue,
enableLights: true,
ledColor: Colors.green,
ledOnMs: 1000, // LED on duration in milliseconds
ledOffMs: 500, // LED off duration in milliseconds
);
}
Show Dialogs
/// Show Dialog with Default Animation
showInDialog(context, builder: (context) => AnyWidget());
/// Show Dialog with Rotate Animation
showInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.ROTATE);
/// Show Dialog with Scale Animation
showInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.SCALE);
/// Show Dialog with Top to Bottom Animation
showInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.SLIDE_TOP_BOTTOM);
/// Show Dialog with Bottom to Top Animation
showInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.SLIDE_BOTTOM_TOP);
/// Show Dialog with Left to Right Animation
showInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.SLIDE_LEFT_RIGHT);
/// Show Dialog with Right to Left Animation
showInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.SLIDE_RIGHT_LEFT);
/// Show Confirmation Dialog
/// Second parameter is Title
showConfirmDialog(
context,
'Do you want to logout from the app?',
onAccept: (context) {
//
},
);
Custom Dialogs
AppButton(
text: "Add",
onTap: () {
showConfirmDialogCustom(
context,
title: "Do you want to add this item?",
dialogType: DialogType.ADD,
onAccept: () {
snackBar(context, title: 'Added');
},
);
},
),
AppButton(
text: "Delete",
onTap: () {
showConfirmDialogCustom(
context,
title: "Delete 89 files permanent?",
dialogType: DialogType.DELETE,
onAccept: () {
snackBar(context, title: 'Deleted');
},
);
},
),
AppButton(
text: "Update",
onTap: () {
showConfirmDialogCustom(
context,
title: "Do you want to update this item?",
dialogType: DialogType.UPDATE,
onAccept: () {
snackBar(context, title: 'Updated');
},
);
},
),
AppButton(
text: "Confirmation with Custom Image",
onTap: () async {
showConfirmDialogCustom(
context,
title: "Do you want to logout from the app?",
dialogType: DialogType.CONFIRMATION,
centerImage: 'URL',
onAccept: () {
//
},
onCancel: () {
//
},
height: 300,
width: 400,
);
},
),
AppButton(
text: "Confirmation",
onTap: () {
showConfirmDialogCustom(
context,
onAccept: () {
snackBar(
context,
title: 'Confirmed',
snackBarAction: SnackBarAction(label: 'label', onPressed: () {}),
);
},
);
},
),
Image Previews
GoogleLogoWidget
Loader Widget
SettingSection
SettingItemWidget
AppButton
UL Widget
AppTextField
HorizontalList Widget
RatingBarWidget
Responsive Widget
DotIndicator Widget
DottedBorderWidget
Features and bugs
Please file feature requests and bugs at the issue tracker.