Jonny Borges
Committed by GitHub

Bump to 2.2.2 version

## [2.2.2]
- Fix GetRoute not found
## [2.2.1]
- Improve lazyPut
## [2.2.0]
- Added: Ability to choose or delay a widget's state change according to its ID.
- Added: Ability to fire triggers when loading materialApp.
- Added: Ability to change theme dynamically.
- Added: Ability to rebuild the entire app with one command.
- Added: Ability to trigger events on the MaterialApp.
- Added: Get.lazyPut (lazy loading of dependencies).
- Added: Get.creator - a factory of dependencies .
- Added: Capability of define abstract class on dependencies.
## [2.1.2]
- Get.defaultDialog refactor
## [2.1.1]
- fix typo
## [2.1.0]
- Added Get.rawSnackbar
- Added instantInit config to snackbars
- Refactor Get Instance Manager
- Improved performance and bug fix to Get State Manager
- Improved performance of GetRoute on namedRoutes
- Hotfix on namedRoutes
## [2.0.10]
- Bump new Flutter version
- Added Get.generalDialog
... ...
# Get
Get is an extra-light and powerful library for Flutter that will give you superpowers and increase your productivity. Navigate without context, open dialogs, snackbars or bottomsheets from anywhere in your code, Manage states and inject dependencies in an easy and practical way! Get is secure, stable, up-to-date, and offers a huge range of APIs that are not present on default framework.
```dart
// Default Flutter navigator
Navigator.of(context).push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return HomePage();
return Home();
},
),
);
... ... @@ -196,16 +197,8 @@ To open default dialog:
```dart
Get.defaultDialog(
title: "My Title",
content: Text("Hi, it's my dialog"),
confirm: FlatButton(
child: Text("Ok"),
onPressed: () => print("OK pressed"),
),
cancel: FlatButton(
child: Text("Cancel"),
onPressed: () => Get.back(),
));
onConfirm: () => print("Ok"),
middleText: "Dialog made in 3 lines of code");
```
You can also use Get.generalDialog instead of showGeneralDialog.
... ... @@ -305,7 +298,7 @@ class OtherClasse extends StatelessWidget {
}
```
If you need to use your controller in many other places, and outside of ReBuilder, just create a get in your controller and have it easily. You can copy this code and just change the name of your controller.
If you need to use your controller in many other places, and outside of GetBuilder, just create a get in your controller and have it easily. (or use `Get.find<Controller>()`)
```dart
class Controller extends GetController {
... ... @@ -313,7 +306,7 @@ class Controller extends GetController {
/// You do not need that. I recommend using it just for ease of syntax.
/// with static method: Controller.to.counter();
/// with no static method: Get.find<Controller>().counter();
/// There is no difference in performance, nor any side effect of using either syntax. Only one does not need the type, and the other does.
/// There is no difference in performance, nor any side effect of using either syntax. Only one does not need the type, and the other the IDE will autocomplete it.
static Controller get to => Get.find(); // add this line
int counter = 0;
... ... @@ -389,7 +382,7 @@ GetBuilder( // you dont need to type on this way
```
## Simple Instance Manager
Are you already using Get and want to make your project as lean as possible? Now Get has a simple instance manager that allows you to retrieve the same class as your Bloc or Controller with just 1 lines of code.
Are you already using Get and want to make your project as lean as possible? Get has a simple and powerful dependency manager that allows you to retrieve the same class as your Bloc or Controller with just 1 lines of code, no Provider context, no inheritedWidget:
```dart
Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();
... ... @@ -415,7 +408,7 @@ Text(controller.textFromApi);
To remove a instance of Get:
```dart
Get.delete(Controller());
Get.delete<Controller>();
```
... ...
... ... @@ -7,6 +7,8 @@ export 'src/bottomsheet/bottomsheet.dart';
export 'src/snackbar/snack_route.dart';
export 'src/state/get_state.dart';
export 'src/root/root_widget.dart';
export 'src/routes/default_route.dart';
export 'src/routes/get_route.dart';
export 'src/routes/observers/route_observer.dart';
export 'src/routes/transitions_type.dart';
export 'src/platform/platform.dart';
... ...
... ... @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'bottomsheet/bottomsheet.dart';
import 'platform/platform.dart';
import 'root/root_controller.dart';
import 'routes/default_route.dart';
import 'routes/observers/route_observer.dart';
import 'routes/transitions_type.dart';
... ... @@ -60,7 +61,7 @@ class Get {
Duration duration,
int id,
bool popGesture}) {
return global(id).currentState.push(GetRoute(
return global(id).currentState.push(GetRouteBase(
opaque: opaque ?? true,
page: page,
popGesture: popGesture ?? _defaultPopGesture,
... ... @@ -136,10 +137,10 @@ class Get {
global(id).currentState.pop(result);
}
/// Experimental API to back from overlay
static void backE({dynamic result}) {
Navigator.pop(overlayContext);
}
// /// Experimental API to back from overlay
// static void backE({dynamic result}) {
// Navigator.pop(overlayContext);
// }
/// It will close as many screens as you define. Times must be> 0;
static void close(int times, [int id]) {
... ... @@ -162,7 +163,7 @@ class Get {
bool popGesture,
int id,
Duration duration}) {
return global(id).currentState.pushReplacement(GetRoute(
return global(id).currentState.pushReplacement(GetRouteBase(
opaque: opaque ?? true,
page: page,
popGesture: popGesture ?? _defaultPopGesture,
... ... @@ -180,7 +181,7 @@ class Get {
var route = (Route<dynamic> rota) => false;
return global(id).currentState.pushAndRemoveUntil(
GetRoute(
GetRouteBase(
opaque: opaque ?? true,
popGesture: popGesture ?? _defaultPopGesture,
page: page,
... ... @@ -232,15 +233,89 @@ class Get {
);
}
static Future<T> defaultDialog<T>(
{String title = "Alert dialog",
static Future<T> defaultDialog<T>({
String title = "Alert",
Widget content,
VoidCallback onConfirm,
VoidCallback onCancel,
VoidCallback onCustom,
String textConfirm,
String textCancel,
String textCustom,
Widget confirm,
Widget cancel,
Widget confirm}) {
return dialog(AlertDialog(
Widget custom,
Color backgroundColor,
Color buttonColor,
String middleText = "Dialog made in 3 lines of code",
double radius = 20.0,
List<Widget> actions,
}) {
Widget cancelButton = cancel ?? (onCancel != null || textCancel != null)
? FlatButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onPressed: () {
onCancel?.call();
Get.back();
},
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: Text(textConfirm ?? "Cancel"),
shape: RoundedRectangleBorder(
side: BorderSide(
color: buttonColor ?? Get.theme.accentColor,
width: 2,
style: BorderStyle.solid),
borderRadius: BorderRadius.circular(100)),
)
: null;
Widget confirmButton = confirm ?? (onConfirm != null || textConfirm != null)
? FlatButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
color: buttonColor ?? Get.theme.accentColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100)),
child: Text(textConfirm ?? "Ok"),
onPressed: () {
onConfirm?.call();
})
: null;
if (actions == null) {
actions = [];
if (cancelButton != null) {
actions.add(cancelButton);
}
if (confirmButton != null) {
actions.add(confirmButton);
}
}
return Get.dialog(AlertDialog(
titlePadding: EdgeInsets.all(8),
contentPadding: EdgeInsets.all(8),
backgroundColor: backgroundColor ?? Get.theme.dialogBackgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(radius))),
title: Text(title, textAlign: TextAlign.center),
content: content,
actions: <Widget>[cancel, confirm],
content: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
content ?? Text(middleText ?? "", textAlign: TextAlign.center),
SizedBox(height: 16),
ButtonTheme(
minWidth: 78.0,
height: 34.0,
child: Wrap(
alignment: WrapAlignment.center,
spacing: 8,
runSpacing: 8,
children: actions,
),
)
],
),
// actions: actions, // ?? <Widget>[cancelButton, confirmButton],
buttonPadding: EdgeInsets.zero,
));
}
... ... @@ -281,9 +356,94 @@ class Get {
));
}
static void rawSnackbar(
{String title,
String message,
Widget titleText,
Widget messageText,
Widget icon,
bool instantInit = false,
bool shouldIconPulse = true,
double maxWidth,
EdgeInsets margin = const EdgeInsets.all(0.0),
EdgeInsets padding = const EdgeInsets.all(16),
double borderRadius = 0.0,
Color borderColor,
double borderWidth = 1.0,
Color backgroundColor = const Color(0xFF303030),
Color leftBarIndicatorColor,
List<BoxShadow> boxShadows,
Gradient backgroundGradient,
FlatButton mainButton,
OnTap onTap,
Duration duration = const Duration(seconds: 3),
bool isDismissible = true,
SnackDismissDirection dismissDirection = SnackDismissDirection.VERTICAL,
bool showProgressIndicator = false,
AnimationController progressIndicatorController,
Color progressIndicatorBackgroundColor,
Animation<Color> progressIndicatorValueColor,
SnackPosition snackPosition = SnackPosition.BOTTOM,
SnackStyle snackStyle = SnackStyle.FLOATING,
Curve forwardAnimationCurve = Curves.easeOutCirc,
Curve reverseAnimationCurve = Curves.easeOutCirc,
Duration animationDuration = const Duration(seconds: 1),
SnackStatusCallback onStatusChanged,
double barBlur = 0.0,
double overlayBlur = 0.0,
Color overlayColor = Colors.transparent,
Form userInputForm}) {
GetBar getBar = GetBar(
title: title,
message: message,
titleText: titleText,
messageText: messageText,
snackPosition: snackPosition,
borderRadius: borderRadius,
margin: margin,
duration: duration,
barBlur: barBlur,
backgroundColor: backgroundColor,
icon: icon,
shouldIconPulse: shouldIconPulse,
maxWidth: maxWidth,
padding: padding,
borderColor: borderColor,
borderWidth: borderWidth,
leftBarIndicatorColor: leftBarIndicatorColor,
boxShadows: boxShadows,
backgroundGradient: backgroundGradient,
mainButton: mainButton,
onTap: onTap,
isDismissible: isDismissible,
dismissDirection: dismissDirection,
showProgressIndicator: showProgressIndicator ?? false,
progressIndicatorController: progressIndicatorController,
progressIndicatorBackgroundColor: progressIndicatorBackgroundColor,
progressIndicatorValueColor: progressIndicatorValueColor,
snackStyle: snackStyle,
forwardAnimationCurve: forwardAnimationCurve,
reverseAnimationCurve: reverseAnimationCurve,
animationDuration: animationDuration,
overlayBlur: overlayBlur,
overlayColor: overlayColor,
userInputForm: userInputForm);
if (instantInit) {
getBar.show();
} else {
SchedulerBinding.instance.addPostFrameCallback((_) {
getBar.show();
});
}
}
static void snackbar(title, message,
{Color colorText,
Duration duration,
/// with instantInit = false you can put Get.snackbar on initState
bool instantInit = false,
SnackPosition snackPosition,
Widget titleText,
Widget messageText,
... ... @@ -315,14 +475,14 @@ class Get {
double overlayBlur,
Color overlayColor,
Form userInputForm}) {
SchedulerBinding.instance.addPostFrameCallback((_) {
final Color defaultColor = IconTheme.of(Get.key.currentContext).color;
return GetBar(
titleText: titleText ??
GetBar getBar = GetBar(
titleText: (title == null)
? null
: titleText ??
Text(
title,
style: TextStyle(
color: colorText ?? defaultColor,
color: colorText ?? theme.iconTheme.color,
fontWeight: FontWeight.w800,
fontSize: 16),
),
... ... @@ -330,7 +490,7 @@ class Get {
Text(
message,
style: TextStyle(
color: colorText ?? defaultColor,
color: colorText ?? theme.iconTheme.color,
fontWeight: FontWeight.w300,
fontSize: 14),
),
... ... @@ -363,10 +523,16 @@ class Get {
animationDuration: animationDuration ?? Duration(seconds: 1),
overlayBlur: overlayBlur ?? 0.0,
overlayColor: overlayColor ?? Colors.transparent,
userInputForm: userInputForm)
..show();
userInputForm: userInputForm);
if (instantInit) {
getBar.show();
} else {
SchedulerBinding.instance.addPostFrameCallback((_) {
getBar.show();
});
}
}
/// change default config of Get
static void config(
... ... @@ -398,6 +564,16 @@ class Get {
}
}
static GetMaterialController getController = GetMaterialController();
static changeTheme(ThemeData theme) {
getController.setTheme(theme);
}
static restartApp() {
getController.restartApp();
}
static Map<int, GlobalKey<NavigatorState>> _keys = {};
static GlobalKey<NavigatorState> nestedKey(int key) {
... ... @@ -416,40 +592,128 @@ class Get {
}
//////////// INSTANCE MANAGER
static Map<dynamic, dynamic> _singl = {};
Map<dynamic, dynamic> _singl = {};
Map<dynamic, _FcBuilderFunc> _factory = {};
static void lazyPut<S>(Object instance) {
final lazy = () => instance;
Get()._factory.putIfAbsent(S, () => lazy);
}
static void lazyPutBuilder<S>(_FcBuilderFunc function) {
Get()._factory.putIfAbsent(S, () => function);
}
/// Register a singleton instance of your class
static T put<T>(T singleton) {
_singl.putIfAbsent(T, () => singleton);
return _singl[T];
/// Inject class on Get Instance Manager
static S put<S>(
S dependency, {
String name,
bool overrideAbstract = false,
_FcBuilderFunc<S> builder,
}) {
_insert(
isSingleton: true,
replace: overrideAbstract,
//?? (("$S" == "${dependency.runtimeType}") == false),
name: name,
builder: builder ?? (() => dependency));
return find<S>(name: name);
}
/// Create a new instance from builder class
/// Example
/// Get.create(() => Repl());
/// Repl a = Get.find();
/// Repl b = Get.find();
/// print(a==b); (false)
static void create<S>(
_FcBuilderFunc<S> builder, {
String name,
}) {
_insert(isSingleton: false, name: name, builder: builder);
}
static void _insert<S>({
bool isSingleton,
String name,
bool replace = true,
_FcBuilderFunc<S> builder,
}) {
assert(builder != null);
String key = _getKey(S, name);
if (replace) {
Get()._singl[key] = _FcBuilder<S>(isSingleton, builder);
} else {
Get()._singl.putIfAbsent(key, () => _FcBuilder<S>(isSingleton, builder));
}
}
/// Find a instance from required class
static S find<S>({String name}) {
if (Get.isRegistred<S>()) {
String key = _getKey(S, name);
_FcBuilder builder = Get()._singl[key];
if (builder == null) {
if (name == null) {
throw "class ${S.toString()} is not register";
} else {
throw "class ${S.toString()} with name '$name' is not register";
}
}
return Get()._singl[key].getSependency();
} else {
if (!Get()._factory.containsKey(S))
throw " $S not found. You need call Get.put<$S>($S()) before";
if (isLogEnable) print('[GET] $S instance was created at that time');
S _value = Get.put<S>(Get()._factory[S].call() as S);
Get()._factory.remove(S);
return _value;
}
}
/// Remove dependency of [S] on dependency abstraction. For concrete class use Get.delete
static void remove<S>({String name}) {
String key = _getKey(S, name);
_FcBuilder builder = Get()._singl[key];
if (builder != null) builder.dependency = null;
if (Get()._singl.containsKey(key)) {
print('error on remove $key');
} else {
if (isLogEnable) print('[GET] $key removed from memory');
}
}
static String _getKey(Type type, String name) {
return name == null ? type.toString() : type.toString() + name;
}
static bool reset() {
_singl.clear();
Get()._singl.clear();
return true;
}
/// Delete a singleton instance of your class
static bool delete<T>(T singleton) {
if (!_singl.containsKey(T)) {
print('key id not found');
/// Delete class instance on [S] and clean memory
static bool delete<S>({String name}) {
String key = _getKey(S, name);
if (!Get()._singl.containsKey(key)) {
print('Instance $key not found');
return false;
}
_singl.removeWhere((oldkey, value) => (oldkey == T));
Get()._singl.removeWhere((oldkey, value) => (oldkey == key));
if (Get()._singl.containsKey(key)) {
print('error on remove object $key');
} else {
if (isLogEnable) print('[GET] $key deleted from memory');
}
return true;
}
/// check if instance is registred
static bool isRegistred<T>() => _singl.containsKey(T);
/// Recover a singleton instance of your class
static T find<T>() {
if (!_singl.containsKey(T)) {
throw 'key id ${T.runtimeType} not found';
}
final recoverKey = _singl[T];
return recoverKey;
}
static bool isRegistred<S>({String name}) =>
Get()._singl.containsKey(_getKey(S, name));
/// give access to Routing API from GetObserver
static Routing get routing => _routing;
... ... @@ -526,8 +790,11 @@ class Get {
/// give access to Theme.of(context)
static ThemeData get theme => Theme.of(context);
/// give access to TextTheme.of(context)
static TextTheme get textTheme => Theme.of(context).textTheme;
/// give access to Mediaquery.of(context)
static MediaQueryData get mediaquery => MediaQuery.of(context);
static MediaQueryData get mediaQuery => MediaQuery.of(context);
/// give access to Theme.of(context).iconTheme.color
static Color get iconColor => Theme.of(context).iconTheme.color;
... ... @@ -542,3 +809,24 @@ class Get {
/// It replaces the Flutter Navigator, but needs no context.
/// You can to use navigator.push(YourRoute()) rather Navigator.push(context, YourRoute());
NavigatorState get navigator => Get.key.currentState;
class _FcBuilder<S> {
bool isSingleton;
_FcBuilderFunc builderFunc;
S dependency;
_FcBuilder(this.isSingleton, this.builderFunc);
S getSependency() {
if (isSingleton) {
if (dependency == null) {
dependency = builderFunc() as S;
}
return dependency;
} else {
return builderFunc() as S;
}
}
}
typedef _FcBuilderFunc<S> = S Function();
... ...
import 'package:flutter/material.dart';
import 'package:get/src/routes/utils/parse_arguments.dart';
import 'package:get/src/state/get_state.dart';
class GetMaterialController extends GetController {
ParseRoute parse = ParseRoute();
Key key = UniqueKey();
ThemeData theme;
void setTheme(ThemeData value) {
theme = value;
update(this);
}
void restartApp() {
key = UniqueKey();
update(this);
}
}
... ...
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/src/routes/get_route.dart';
import 'package:get/src/routes/utils/parse_arguments.dart';
import 'root_controller.dart';
class GetMaterialApp extends StatefulWidget {
class GetMaterialApp extends StatelessWidget {
const GetMaterialApp({
Key key,
this.navigatorKey,
... ... @@ -17,6 +19,8 @@ class GetMaterialApp extends StatefulWidget {
this.title = '',
this.onGenerateTitle,
this.color,
this.onInit,
this.onDispose,
this.theme,
this.darkTheme,
this.themeMode = ThemeMode.system,
... ... @@ -84,6 +88,8 @@ class GetMaterialApp extends StatefulWidget {
final Function(Routing) routingCallback;
final Transition defaultTransition;
final bool opaqueRoute;
final VoidCallback onInit;
final VoidCallback onDispose;
final bool enableLog;
final bool popGesture;
final Duration transitionDuration;
... ... @@ -91,31 +97,6 @@ class GetMaterialApp extends StatefulWidget {
final Map<String, GetRoute> namedRoutes;
final GetRoute unknownRoute;
@override
_GetMaterialAppState createState() => _GetMaterialAppState();
}
class _GetMaterialAppState extends State<GetMaterialApp> {
ParseRoute parse = ParseRoute();
@override
void initState() {
if (widget.namedRoutes != null) {
widget.namedRoutes.forEach((key, value) {
parse.addRoute(key);
});
}
Get.config(
enableLog: widget.enableLog ?? Get.isLogEnable,
defaultTransition: widget.defaultTransition ?? Get.defaultTransition,
defaultOpaqueRoute: widget.opaqueRoute ?? Get.isOpaqueRouteDefault,
defaultPopGesture: widget.popGesture ?? Get.isPopGestureEnable,
defaultDurationTransition:
widget.transitionDuration ?? Get.defaultDurationTransition,
defaultGlobalState: widget.defaultGlobalState ?? Get.defaultGlobalState,
);
super.initState();
}
Route<dynamic> namedRoutesGenerate(RouteSettings settings) {
Get.setSettings(settings);
// final parsedString = parse.split(settings.name);
... ... @@ -124,87 +105,132 @@ class _GetMaterialAppState extends State<GetMaterialApp> {
/// workaround until they fix it, because the problem is with the 'Flutter engine',
/// which changes the initial route for an empty String, not the main Flutter,
/// so only Team can fix it.
final parsedString = parse.split(
settings.name == '' ? (widget.initialRoute ?? '/') : settings.name);
var parsedString = Get.getController.parse.split(
(settings.name == '' || settings.name == null)
? (initialRoute ?? '/')
: settings.name);
if (parsedString == null) {
parsedString = AppRouteMatch();
parsedString.route = settings.name;
}
String settingsname = parsedString.route;
String settingsName = parsedString.route;
Map<String, GetRoute> newNamedRoutes = {};
widget.namedRoutes.forEach((key, value) {
String newName = parse.split(key).route;
namedRoutes.forEach((key, value) {
String newName = Get.getController.parse.split(key).route;
newNamedRoutes.addAll({newName: value});
});
if (newNamedRoutes.containsKey(settingsname)) {
if (newNamedRoutes.containsKey(settingsName)) {
Get.setParameter(parsedString.parameters);
return GetRoute(
page: newNamedRoutes[settingsname].page,
title: newNamedRoutes[settingsname].title,
return GetRouteBase(
page: newNamedRoutes[settingsName].page,
title: newNamedRoutes[settingsName].title,
parameter: parsedString.parameters,
settings:
RouteSettings(name: settings.name, arguments: settings.arguments),
maintainState: newNamedRoutes[settingsname].maintainState,
curve: newNamedRoutes[settingsname].curve,
alignment: newNamedRoutes[settingsname].alignment,
opaque: newNamedRoutes[settingsname].opaque,
transitionDuration: (widget.transitionDuration == null
? newNamedRoutes[settingsname].transitionDuration
: widget.transitionDuration),
transition: newNamedRoutes[settingsname].transition,
popGesture: newNamedRoutes[settingsname].popGesture,
fullscreenDialog: newNamedRoutes[settingsname].fullscreenDialog,
maintainState: newNamedRoutes[settingsName].maintainState,
curve: newNamedRoutes[settingsName].curve,
alignment: newNamedRoutes[settingsName].alignment,
opaque: newNamedRoutes[settingsName].opaque,
transitionDuration: (transitionDuration == null
? newNamedRoutes[settingsName].transitionDuration
: transitionDuration),
transition: newNamedRoutes[settingsName].transition,
popGesture: newNamedRoutes[settingsName].popGesture,
fullscreenDialog: newNamedRoutes[settingsName].fullscreenDialog,
);
} else {
return (widget.unknownRoute ??
GetRoute(
return ((unknownRoute == null
? GetRouteBase(
page: Scaffold(
body: Center(
child: Text("Route not found :("),
),
))
: GetRouteBase(
page: unknownRoute.page,
title: unknownRoute.title,
settings: unknownRoute.settings,
maintainState: unknownRoute.maintainState,
curve: unknownRoute.curve,
alignment: unknownRoute.alignment,
parameter: unknownRoute.parameter,
opaque: unknownRoute.opaque,
transitionDuration: unknownRoute.transitionDuration,
popGesture: unknownRoute.popGesture,
transition: unknownRoute.transition,
fullscreenDialog: unknownRoute.fullscreenDialog,
)));
}
}
@override
Widget build(BuildContext context) {
return GetBuilder<GetMaterialController>(
init: Get.getController,
dispose: (d) {
onDispose?.call();
},
initState: (i) {
onInit?.call();
if (namedRoutes != null) {
namedRoutes.forEach((key, value) {
Get.getController.parse.addRoute(key);
});
}
Get.config(
enableLog: enableLog ?? Get.isLogEnable,
defaultTransition: defaultTransition ?? Get.defaultTransition,
defaultOpaqueRoute: opaqueRoute ?? Get.isOpaqueRouteDefault,
defaultPopGesture: popGesture ?? Get.isPopGestureEnable,
defaultDurationTransition:
transitionDuration ?? Get.defaultDurationTransition,
defaultGlobalState: defaultGlobalState ?? Get.defaultGlobalState,
);
},
builder: (_) {
return MaterialApp(
navigatorKey: (widget.navigatorKey == null
? Get.key
: Get.addKey(widget.navigatorKey)),
home: widget.home,
routes: widget.routes ?? const <String, WidgetBuilder>{},
initialRoute: widget.initialRoute,
onGenerateRoute: (widget.namedRoutes == null
? widget.onGenerateRoute
: namedRoutesGenerate),
onGenerateInitialRoutes: widget.onGenerateInitialRoutes,
onUnknownRoute: widget.onUnknownRoute,
navigatorObservers: (widget.navigatorObservers == null
? <NavigatorObserver>[GetObserver(widget.routingCallback)]
: <NavigatorObserver>[GetObserver(widget.routingCallback)]
..addAll(widget.navigatorObservers)),
builder: widget.builder,
title: widget.title ?? '',
onGenerateTitle: widget.onGenerateTitle,
color: widget.color,
theme: widget.theme,
darkTheme: widget.darkTheme,
themeMode: widget.themeMode ?? ThemeMode.system,
locale: widget.locale,
localizationsDelegates: widget.localizationsDelegates,
localeListResolutionCallback: widget.localeListResolutionCallback,
localeResolutionCallback: widget.localeResolutionCallback,
key: _.key,
navigatorKey:
(navigatorKey == null ? Get.key : Get.addKey(navigatorKey)),
home: home,
routes: routes ?? const <String, WidgetBuilder>{},
initialRoute: initialRoute,
onGenerateRoute:
(namedRoutes == null ? onGenerateRoute : namedRoutesGenerate),
onGenerateInitialRoutes: onGenerateInitialRoutes,
onUnknownRoute: onUnknownRoute,
navigatorObservers: (navigatorObservers == null
? <NavigatorObserver>[GetObserver(routingCallback)]
: <NavigatorObserver>[GetObserver(routingCallback)]
..addAll(navigatorObservers)),
builder: builder,
title: title ?? '',
onGenerateTitle: onGenerateTitle,
color: color,
theme: theme ?? _.theme ?? ThemeData.fallback(),
darkTheme: darkTheme,
themeMode: themeMode ?? ThemeMode.system,
locale: locale,
localizationsDelegates: localizationsDelegates,
localeListResolutionCallback: localeListResolutionCallback,
localeResolutionCallback: localeResolutionCallback,
supportedLocales:
widget.supportedLocales ?? const <Locale>[Locale('en', 'US')],
debugShowMaterialGrid: widget.debugShowMaterialGrid ?? false,
showPerformanceOverlay: widget.showPerformanceOverlay ?? false,
supportedLocales ?? const <Locale>[Locale('en', 'US')],
debugShowMaterialGrid: debugShowMaterialGrid ?? false,
showPerformanceOverlay: showPerformanceOverlay ?? false,
checkerboardRasterCacheImages:
widget.checkerboardRasterCacheImages ?? false,
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers ?? false,
showSemanticsDebugger: widget.showSemanticsDebugger ?? false,
debugShowCheckedModeBanner: widget.debugShowCheckedModeBanner ?? true,
shortcuts: widget.shortcuts,
// actions: widget.actions,
checkerboardRasterCacheImages ?? false,
checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false,
showSemanticsDebugger: showSemanticsDebugger ?? false,
debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true,
shortcuts: shortcuts,
// actions: actions,
);
});
}
}
... ...
... ... @@ -18,10 +18,10 @@ const int _kMaxDroppedSwipePageForwardAnimationTime = 800; // Milliseconds.
// user releases a page mid swipe.
const int _kMaxPageBackAnimationTime = 300;
class GetRoute<T> extends PageRoute<T> {
class GetRouteBase<T> extends PageRoute<T> {
/// The [builder], [maintainState], and [fullscreenDialog] arguments must not
/// be null.
GetRoute({
GetRouteBase({
@required this.page,
this.title,
RouteSettings settings,
... ... @@ -85,7 +85,7 @@ class GetRoute<T> extends PageRoute<T> {
@override
void didChangePrevious(Route<dynamic> previousRoute) {
final String previousTitleString =
previousRoute is GetRoute ? previousRoute.title : null;
previousRoute is GetRouteBase ? previousRoute.title : null;
if (_previousTitle == null) {
_previousTitle = ValueNotifier<String>(previousTitleString);
} else {
... ... @@ -113,7 +113,7 @@ class GetRoute<T> extends PageRoute<T> {
@override
bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {
// Don't perform outgoing animation if the next route is a fullscreen dialog.
return nextRoute is GetRoute && !nextRoute.fullscreenDialog;
return nextRoute is GetRouteBase && !nextRoute.fullscreenDialog;
}
/// True if an iOS-style back swipe pop gesture is currently underway for [route].
... ...
import 'package:flutter/widgets.dart';
import 'transitions_type.dart';
class GetRoute {
final Widget page;
final bool popGesture;
final Map<String, String> parameter;
final String title;
final Transition transition;
final Curve curve;
final Alignment alignment;
final bool maintainState;
final bool opaque;
final Duration transitionDuration;
final bool fullscreenDialog;
final RouteSettings settings;
GetRoute({
@required this.page,
this.title,
this.settings,
this.maintainState = true,
this.curve = Curves.linear,
this.alignment,
this.parameter,
this.opaque = true,
this.transitionDuration = const Duration(milliseconds: 400),
this.popGesture,
this.transition,
this.fullscreenDialog = false,
}) : assert(page != null),
assert(maintainState != null),
assert(fullscreenDialog != null);
}
... ...
import 'package:flutter/material.dart';
import '../get_main.dart';
class RealState {
final State state;
final String id;
RealState({this.state, this.id});
}
class GetController extends State {
Map<GetController, State> _allStates = {};
Map<GetController, List<RealState>> _allStates = {};
/// Update GetBuilder with update(this)
void update(GetController id) {
if (id != null) {
final State state = _allStates[id];
if (state != null && state.mounted) state.setState(() {});
void update(GetController controller, [List<String> ids]) {
if (controller != null) {
if (ids == null) {
var all = _allStates[controller];
all.forEach((rs) {
if (rs.state != null && rs.state.mounted) rs.state.setState(() {});
});
} else {
ids.forEach(
(s) {
var all = _allStates[controller];
all.forEach((rs) {
if (rs.state != null && rs.state.mounted && rs.id == s)
rs.state.setState(() {});
});
},
);
}
}
}
... ... @@ -20,6 +40,7 @@ class GetBuilder<T extends GetController> extends StatefulWidget {
@required
final Widget Function(T) builder;
final bool global;
final String id;
final bool autoRemove;
final void Function(State state) initState, dispose, didChangeDependencies;
final void Function(GetBuilder oldWidget, State state) didUpdateWidget;
... ... @@ -32,6 +53,7 @@ class GetBuilder<T extends GetController> extends StatefulWidget {
this.autoRemove = true,
this.initState,
this.dispose,
this.id,
this.didChangeDependencies,
this.didUpdateWidget,
}) : assert(builder != null),
... ... @@ -48,14 +70,24 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> {
if (widget.global) {
if (Get.isRegistred<T>()) {
controller = Get.find<T>();
if (controller._allStates[controller] == null) {
controller._allStates[controller] = [];
}
controller._allStates[controller]
.add(RealState(state: this, id: widget.id));
} else {
controller = widget.init;
controller._allStates[controller] = this;
Get.put(controller);
if (controller._allStates[controller] == null) {
controller._allStates[controller] = [];
}
controller._allStates[controller]
.add(RealState(state: this, id: widget.id));
Get.put<T>(controller);
}
} else {
controller = widget.init;
controller._allStates[controller] = this;
controller._allStates[controller]
.add(RealState(state: this, id: widget.id));
}
if (widget.initState != null) widget.initState(this);
}
... ... @@ -67,11 +99,24 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> {
if (b._allStates[controller].hashCode == this.hashCode) {
b._allStates.remove(controller);
}
} else {
var b = controller;
if (b._allStates[controller].hashCode == this.hashCode) {
b._allStates.remove(controller);
}
}
if (widget.dispose != null) widget.dispose(this);
if (widget.autoRemove && Get.isRegistred<T>() && (widget.init != null)) {
Get.delete(widget.init);
if (widget.init != null) {
if (widget.autoRemove && Get.isRegistred<T>()) {
Get.delete<T>();
}
} else {
// controller._allStates[controller].remove(this);
controller._allStates[controller]
.remove(RealState(state: this, id: widget.id));
}
super.dispose();
}
... ...
name: get
description: Navigate between screens, display snackbars, dialogs and bottomSheets, from anywhere in your code without context with Get.
version: 2.0.10
description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
version: 2.2.2
homepage: https://github.com/jonataslaw/get
environment:
... ...