nb_utils는 앱 개발을 간소화하기 위해 필수적인 위젯과 유틸리티 메서드의 컬렉션을 제공하는 포괄적인 Flutter 패키지입니다. 일반적인 UI 및 로직 문제를 해결하는 재사용 가능한 구성 요소와 보조 함수를 제공하여 빌더플레이트 코드를 줄입니다. Android, iOS, Web, macOS, Windows, Linux 등 모든 주요 플랫폼에서 지원되며, 크로스플랫폼 애플리케이션을 개발하는 개발자의 생산성을 향상시킵니다. 일관되고 잘 구조화된 도구를 사용하여 기능 구현을 가속화하기에 이상적입니다.
사용 사례
빠른 UI 프로토타이핑
일반적인 위젯 재사용
크로스 플랫폼 개발
양식 처리 유틸리티
빠른 탐색 설정
상태 관리 단축키
주요 기능
사전 구축된 UI 컴포넌트
광범위한 유틸리티 메서드
플랫폼에 관계없는 설계
pub를 통한 간편한 통합
일관된 스타일링 도우미
시간 절약 개발 도구
적합한 대상
초보자에서 고급까지의 플러터 개발자
빠르게 진행되는 프로젝트 팀
일관된 UI 패턴이 필요한 앱
보일러플레이트를 줄이려는 개발자
엄격한 마감일이 있는 프로젝트
고려 사항
패키지 크기가 약간 증가할 수 있습니다
일부 위젯에서 사용자 지정 기능이 제한되어 있습니다
외부 종속성에 의존합니다
모듈식 아키텍처와 함께 사용하는 것이 가장 좋습니다
매우 전문적인 UI에는 적합하지 않습니다
기본적인 Dart/Flutter 이해 필요
원본 README
연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
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 nb_utils
Import package
import'package:nb_utils/nb_utils.dart';
Initialize nb_utils in main.dart file for initializing Shared Preferences and other variables.
Also you can assign your Chat GPT key here.
/// Open a new screenHomePage().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 screenHomePage().launch(context, isNewTask: true);
// Returns to previous Screenfinish(context);
// Returns to previous Screen with a resultfinish(context, object);
/// Toast a Stringtoast('This is a string');
/// Prints only if in debug or profile mode - (parameter is Object)log('Your string');
voidhideKeyboard(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)awaitgetPackageName();
/// Get Package Name, Version Code, Version Name (Android, iOS)awaitgetPackageInfo();
/// Return true if Android OS version is above 12Future<bool> isAndroid12Above()
/// Handle error and loading widget when using FutureBuilder or StreamBuilder/// "snap" is the snapShot value we get from FutureBuilder or StreamBuilderreturnsnapWidgetHelper(snap);
/// See the example below. You can Use FutureBuilder or StreamBuilder.FutureBuilder(
builder(_, snap) {
if (snap.hasData) {
returnYourWidget();
} else {
/// This function will handle loading and error automatically./// You can modify loading and error widget in parameters.returnsnapWidgetHelper(snap);
}
}
),
// Basic SnackBarsnackBar(context, title: 'Sample toast'),
// EnhancedsnackBar(
context,
title: 'Sample toast',
textColor: Colors.blue,
backgroundColor: Colors.white,
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: radius(30)),
margin: EdgeInsets.all(16),
duration: 3.seconds,
);
/// 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 SharedPrefawaitsetValue("key", 20.0);
/// add a bool in SharedPrefawaitsetValue("key", false);
/// add a int in SharedPrefawaitsetValue("key", 10);
/// add a String in SharedPrefawaitsetValue("key", "value");
/// add a String List in SharedPrefawaitsetValue("key", ['value', 'value', 'value']);
/// Returns a Bool if exists in SharedPref/// You can set a default value if it returns nullgetBoolAsync("key");
/// Returns a Double if exists in SharedPrefgetDoubleAsync("key");
/// Returns a Int if exists in SharedPrefgetIntAsync("key");
/// Returns a String if exists in SharedPrefgetStringAsync("key");
/// Returns a JSON if exists in SharedPrefgetJSONAsync("key");
/// Remove a key from SharedPrefawaitremoveKey("key");
/// Returns List of Keys that matches with given KeygetMatchingSharedPrefKeys('key')
BorderRadiusradius([double? radius])
RadiusradiusCircular([double? radius])
BorderRadiusradiusOnly({double? topRight,double? topLeft,double? bottomRight,double? bottomLeft,})
ShapeBorderdialogShape([double? borderRadius])
/// Apply default BoxDecoration with default shadow and border radiusContainer(
decoration: boxDecorationDefault(), // You can modify based on your preference
),
InputDecorationdefaultInputDecoration({String? hint, String? label, TextStyle? textStyle})
Widgets
/// Give Blur effect to any widget/// Use Blur widget to know more properiesBlur(
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 notHoverWidget(
builder: (_, isHovering) {
returnAnyWidget();
},
),
/// Wrap MaterialApp Widget with RestartAppWidget/// Use: RestartAppWidget.init(context);/// Call above line any where to restart your Flutter app.RestartAppWidget(
child: MaterialApp(),
)
/// Default AppButton/// Use AppButton on your app to try more propertiesAppButton(
text: "Submit",
color: Colors.green, // Optional
onTap: () {
//Your logic
},
),
/// Use PlaceHolderWidget while your network image is loadingPlaceHolderWidget(),
/// Use GradientBorder while your network image is loadingGradientBorder(
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 widgetRoundedCheckBox(
isChecked: true,
text: 'Remember me',
onTap: (val) {
//
},
),
/// Use SizeListener widget to get callback when its child widget size changesSizeListener(
child: AnyWidget(),
onSizeChange: (size) {
log(size.width.toString());
},
),
/// Add read more button to a long textReadMoreText(
'Long Text',
),
/// Build Horizontal List widget without giving specific height to it.HorizontalList(
itemBuilder: (BuildContext context, int index) {
returnAnyWidget();
},
itemCount: 25,
),
/// Make your Flutter App Responsive in any device out there with Responsive widgetResponsive(
mobile: MobileWidget(),
tablet: TabletWidget(), // Optional
web: WebWidget(), // Optional
),
/// Use SnapHelperWidget to handle loading and error widget automatically/// Still you can specify custom Loader Widget and Error WidgetSnapHelperWidget<T>(
future: future,
onSuccess: (data) {
returnAnyWidget();
},
),
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"),
),
/// You can use .timeAgo on a DateTime object like thisString result = DateTime.now().timeAgo;
boolget isToday
boolget isYesterday
boolget isTomorrow
/// return current time in millisecondsintcurrentMillisecondsTimeStamp()
/// return current timestampintcurrentTimeStamp()
boolleapYear(int year)
/// returns how much time ago from timestampStringformatTime(int timestamp)
/// returns number of days in given monthintdaysInMonth(int monthNum, int year)
doublevalidate({double value = 0.0})
boolisBetween(num first, num second)
Sizeget 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.intvalidate({int value = 0})
/// Leaves given height of space ex: 16.height,Widgetget height
/// Leaves given width of space ex: 16.width,Widgetget width
/// HTTP status codeboolisSuccessful()
BorderRadiusborderRadius([double? val])
/// Returns microseconds duration/// 5.microsecondsDurationget microseconds
Durationget milliseconds
Durationget seconds
Durationget minutes
Durationget hours
Durationget days
boolisBetween(num first, num second)
Sizeget size
// return suffix (th,st,nd,rd) of the given month day numberStringtoMonthDaySuffix()
// returns month name from the given intStringtoMonthName({bool isHalfName = false})
// returns WeekDay from the given intStringtoWeekDay({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 elementvoidforEachIndexed(voidaction(T element, int index))
intsumBy(intFunction(T) selector)
doublesumByDouble(numFunction(T) selector)
double?averageBy(numFunction(T) selector)
num Extensions
/// Validate given double is not null and returns given value if null.numvalidate({num value = 0})
/// Returns price with currencyStringtoCurrencyAmount()
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();
/// Change status bar Color and BrightnesssetStatusBarColor(Colors.blue);
setDarkStatusBar();
setLightStatusBar();
/// Show Status BarshowStatusBar();
/// Hide Status BarhideStatusBar();
/// Set orientation to portraitsetOrientationPortrait();
/// Set orientation to landscapesetOrientationLandscape();
/// Get current PlatformName as a StringStringplatformName();
/// 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 ClipboardFuture<String> paste();
/// Invoke Native method and get resultvar data = awaitinvokeNativeMethod(CHANNEL_NAME, METHOD_NAME, [dynamic arguments]);
/// Pass your token here to get Map<String, dynamic>Map<String, dynamic> JwtDecoder.decode(token);
boolJwtDecoder.isExpired(token);
DateTimeJwtDecoder.getExpirationDate(token);
DurationJwtDecoder.getTokenTime(token);
DurationJwtDecoder.getRemainingTime(token);
Show Dialogs
/// Show Dialog with Default AnimationshowInDialog(context, builder: (context) => AnyWidget());
/// Show Dialog with Rotate AnimationshowInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.ROTATE);
/// Show Dialog with Scale AnimationshowInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.SCALE);
/// Show Dialog with Top to Bottom AnimationshowInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.SLIDE_TOP_BOTTOM);
/// Show Dialog with Bottom to Top AnimationshowInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.SLIDE_BOTTOM_TOP);
/// Show Dialog with Left to Right AnimationshowInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.SLIDE_LEFT_RIGHT);
/// Show Dialog with Right to Left AnimationshowInDialog(context, builder: (context) => AnyWidget(), dialogAnimation: DialogAnimation.SLIDE_RIGHT_LEFT);
/// Show Confirmation Dialog/// Second parameter is TitleshowConfirmDialog(
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');
},
);
},
),