Jonny Borges
Committed by GitHub

Added sort method to ListX

## [2.12.6]
## [2.13.1]
- Added sort to ListX
- Prepared the framework for version 3
## [2.13.0]
- Added Get.focusScope
## [2.13.0]
- Update docs
- Fix Bindings list on GetRouteBase
... ...
... ... @@ -20,3 +20,4 @@ export 'src/routes/bindings_interface.dart';
export 'src/routes/observers/route_observer.dart';
export 'src/routes/transitions_type.dart';
export 'src/platform/platform.dart';
export 'src/extension_instance.dart';
... ...
import 'get_instance.dart';
import 'get_main.dart';
import 'typedefs/typedefs.dart';
extension Storage on GetImpl {
void lazyPut<S>(FcBuilderFunc builder, {String tag}) {
return GetInstance().lazyPut<S>(builder, tag: tag);
}
Future<S> putAsync<S>(FcBuilderFuncAsync<S> builder, {String tag}) async =>
GetInstance().putAsync<S>(builder, tag: tag);
S find<S>({String tag, FcBuilderFunc<S> instance}) =>
GetInstance().find<S>(tag: tag, instance: instance);
S put<S>(S dependency,
{String tag,
bool permanent = false,
bool overrideAbstract = false,
FcBuilderFunc<S> builder}) =>
GetInstance().put<S>(dependency,
tag: tag,
permanent: permanent,
overrideAbstract: overrideAbstract,
builder: builder);
bool reset({bool clearFactory = true, bool clearRouteBindings = true}) =>
GetInstance().reset(
clearFactory: clearFactory, clearRouteBindings: clearRouteBindings);
}
... ...
import 'root/smart_management.dart';
import 'rx/rx_interface.dart';
import 'typedefs/typedefs.dart';
class GetConfig {
//////////// INSTANCE MANAGER
static Map<dynamic, dynamic> _singl = {};
static Map<dynamic, FcBuilderFunc> _factory = {};
static Map<String, String> routesKey = {};
static SmartManagement smartManagement = SmartManagement.full;
static bool isLogEnable = true;
static String currentRoute;
}
class GetInstance {
factory GetInstance() {
if (_getInstance == null) _getInstance = GetInstance._();
return _getInstance;
}
GetInstance._();
static GetInstance _getInstance;
void lazyPut<S>(FcBuilderFunc builder, {String tag}) {
String key = _getKey(S, tag);
GetConfig._factory.putIfAbsent(key, () => builder);
}
Future<S> putAsync<S>(FcBuilderFuncAsync<S> builder, {String tag}) async {
return put<S>(await builder(), tag: tag);
}
/// Inject class on Get Instance Manager
S put<S>(
S dependency, {
String tag,
bool permanent = false,
bool overrideAbstract = false,
FcBuilderFunc<S> builder,
}) {
_insert(
isSingleton: true,
replace: overrideAbstract,
//?? (("$S" == "${dependency.runtimeType}") == false),
name: tag,
permanent: permanent,
builder: builder ?? (() => dependency));
return find<S>(tag: tag);
}
/// Create a new instance from builder class
/// Example
/// create(() => Repl());
/// Repl a = find();
/// Repl b = find();
/// print(a==b); (false)
void create<S>(
FcBuilderFunc<S> builder, {
String name,
}) {
_insert(isSingleton: false, name: name, builder: builder);
}
void _insert<S>({
bool isSingleton,
String name,
bool replace = true,
bool permanent = false,
FcBuilderFunc<S> builder,
}) {
assert(builder != null);
String key = _getKey(S, name);
if (replace) {
GetConfig._singl[key] = FcBuilder<S>(isSingleton, builder, permanent);
} else {
GetConfig._singl.putIfAbsent(
key, () => FcBuilder<S>(isSingleton, builder, permanent));
}
}
void removeDependencyByRoute(String routeName) async {
List<String> keysToRemove = [];
GetConfig.routesKey.forEach((key, value) {
// if (value == routeName && value != null) {
if (value == routeName) {
keysToRemove.add(key);
}
});
keysToRemove.forEach((element) async {
await delete(key: element);
});
keysToRemove.forEach((element) {
GetConfig.routesKey?.remove(element);
});
keysToRemove.clear();
}
bool isRouteDependecyNull<S>({String name}) {
return (GetConfig.routesKey[_getKey(S, name)] == null);
}
bool isDependencyInit<S>({String name}) {
String key = _getKey(S, name);
return GetConfig.routesKey.containsKey(key);
}
void registerRouteInstance<S>({String tag}) {
// print("Register route [$S] as ${currentRoute}");
GetConfig.routesKey
.putIfAbsent(_getKey(S, tag), () => GetConfig.currentRoute);
}
S findByType<S>(Type type, {String tag}) {
String key = _getKey(type, tag);
return GetConfig._singl[key].getSependency();
}
void initController<S>({String tag}) {
String key = _getKey(S, tag);
final i = GetConfig._singl[key].getSependency();
if (i is DisposableInterface) {
i.onStart();
if (GetConfig.isLogEnable) print('[GET] $key has been initialized');
}
}
/// Find a instance from required class
S find<S>({String tag, FcBuilderFunc<S> instance}) {
String key = _getKey(S, tag);
bool callInit = false;
if (isRegistred<S>(tag: tag)) {
if (!isDependencyInit<S>() &&
GetConfig.smartManagement != SmartManagement.onlyBuilder) {
registerRouteInstance<S>(tag: tag);
callInit = true;
}
FcBuilder builder = GetConfig._singl[key];
if (builder == null) {
if (tag == null) {
throw "class ${S.toString()} is not register";
} else {
throw "class ${S.toString()} with tag '$tag' is not register";
}
}
if (callInit) {
initController<S>(tag: tag);
}
return GetConfig._singl[key].getSependency();
} else {
if (!GetConfig._factory.containsKey(key))
throw " $S not found. You need call put<$S>($S()) before";
if (GetConfig.isLogEnable)
print('[GET] $S instance was created at that time');
S _value = put<S>(GetConfig._factory[key].call() as S);
if (!isDependencyInit<S>() &&
GetConfig.smartManagement != SmartManagement.onlyBuilder) {
registerRouteInstance<S>(tag: tag);
callInit = true;
}
if (GetConfig.smartManagement != SmartManagement.keepFactory) {
GetConfig._factory.remove(key);
}
if (callInit) {
initController<S>(tag: tag);
}
return _value;
}
}
/// Remove dependency of [S] on dependency abstraction. For concrete class use delete
void remove<S>({String tag}) {
String key = _getKey(S, tag);
FcBuilder builder = GetConfig._singl[key];
final i = builder.dependency;
if (i is DisposableInterface) {
i.onClose();
if (GetConfig.isLogEnable) print('[GET] onClose of $key called');
}
if (builder != null) builder.dependency = null;
if (GetConfig._singl.containsKey(key)) {
print('error on remove $key');
} else {
if (GetConfig.isLogEnable) print('[GET] $key removed from memory');
}
}
String _getKey(Type type, String name) {
return name == null ? type.toString() : type.toString() + name;
}
bool reset({bool clearFactory = true, bool clearRouteBindings = true}) {
if (clearFactory) GetConfig._factory.clear();
if (clearRouteBindings) GetConfig.routesKey.clear();
GetConfig._singl.clear();
return true;
}
/// Delete class instance on [S] and clean memory
Future<bool> delete<S>({String tag, String key}) async {
String newKey;
if (key == null) {
newKey = _getKey(S, tag);
} else {
newKey = key;
}
if (!GetConfig._singl.containsKey(newKey)) {
print('Instance $newKey not found');
return false;
}
FcBuilder builder = GetConfig._singl[newKey];
if (builder.permanent) {
(key == null)
? print(
'[GET] [$newKey] has been marked as permanent, SmartManagement is not authorized to delete it.')
: print(
'[GET] [$newKey] has been marked as permanent, SmartManagement is not authorized to delete it.');
return false;
}
final i = builder.dependency;
if (i is DisposableInterface) {
await i.onClose();
if (GetConfig.isLogEnable) print('[GET] onClose of $newKey called');
}
GetConfig._singl.removeWhere((oldkey, value) => (oldkey == newKey));
if (GetConfig._singl.containsKey(newKey)) {
print('[GET] error on remove object $newKey');
} else {
if (GetConfig.isLogEnable) print('[GET] $newKey deleted from memory');
}
// GetConfig.routesKey?.remove(key);
return true;
}
/// check if instance is registred
bool isRegistred<S>({String tag}) =>
GetConfig._singl.containsKey(_getKey(S, tag));
/// check if instance is prepared
bool isPrepared<S>({String tag}) =>
GetConfig._factory.containsKey(_getKey(S, tag));
}
... ...
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:get/get.dart';
import 'root/root_controller.dart';
import 'routes/bindings_interface.dart';
import 'routes/transitions_type.dart';
import 'snackbar/snack.dart';
///Use Get.to instead of Navigator.push, Get.off instead of Navigator.pushReplacement,
///Get.offAll instead of Navigator.pushAndRemoveUntil. For named routes just add "named"
///after them. Example: Get.toNamed, Get.offNamed, and Get.AllNamed.
///To return to the previous screen, use Get.back().
///No need to pass any context to Get, just put the name of the route inside
///the parentheses and the magic will occur.
///
abstract class GetService {
/// It replaces Navigator.push, but needs no context, and it doesn't have the Navigator.push
/// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
/// of rebuilding every app after a route, use opaque = true as the parameter.
Future<T> to<T>(Widget page,
{bool opaque,
Transition transition,
Duration duration,
int id,
bool fullscreenDialog = false,
Object arguments,
Bindings binding,
bool popGesture});
/// It replaces Navigator.pushNamed, but needs no context, and it doesn't have the Navigator.pushNamed
/// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
/// of rebuilding every app after a route, use opaque = true as the parameter.
Future<T> toNamed<T>(String page, {Object arguments, int id});
/// It replaces Navigator.pushReplacementNamed, but needs no context.
Future<T> offNamed<T>(String page, {Object arguments, int id});
/// It replaces Navigator.popUntil, but needs no context.
void until(RoutePredicate predicate, {int id});
/// It replaces Navigator.pushAndRemoveUntil, but needs no context.
Future<T> offUntil<T>(Route<T> page, RoutePredicate predicate, {int id});
/// It replaces Navigator.pushNamedAndRemoveUntil, but needs no context.
Future<T> offNamedUntil<T>(String page, RoutePredicate predicate,
{int id, Object arguments});
/// It replaces Navigator.popAndPushNamed, but needs no context.
Future<T> offAndToNamed<T>(String page,
{Object arguments, int id, dynamic result});
/// It replaces Navigator.removeRoute, but needs no context.
void removeRoute(Route<dynamic> route, {int id});
/// It replaces Navigator.pushNamedAndRemoveUntil, but needs no context.
Future<T> offAllNamed<T>(String newRouteName,
{RoutePredicate predicate, Object arguments, int id});
bool get isOverlaysOpen;
bool get isOverlaysClosed;
/// It replaces Navigator.pop, but needs no context.
void back({dynamic result, bool closeOverlays = false, int id});
/// It will close as many screens as you define. Times must be> 0;
void close(int times, [int id]);
/// It replaces Navigator.pushReplacement, but needs no context, and it doesn't have the Navigator.pushReplacement
/// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
/// of rebuilding every app after a route, use opaque = true as the parameter.
Future<T> off<T>(Widget page,
{bool opaque = false,
Transition transition,
bool popGesture,
int id,
Object arguments,
Bindings binding,
bool fullscreenDialog = false,
Duration duration});
/// It replaces Navigator.pushAndRemoveUntil, but needs no context
Future<T> offAll<T>(Widget page,
{RoutePredicate predicate,
bool opaque = false,
bool popGesture,
int id,
Object arguments,
Bindings binding,
bool fullscreenDialog = false,
Transition transition});
/// Show a dialog
Future<T> dialog<T>(
Widget child, {
bool barrierDismissible = true,
bool useRootNavigator = true,
// RouteSettings routeSettings
});
/// Api from showGeneralDialog with no context
Future<T> generalDialog<T>({
@required RoutePageBuilder pageBuilder,
String barrierLabel = "Dismiss",
bool barrierDismissible = true,
Color barrierColor = const Color(0x80000000),
Duration transitionDuration = const Duration(milliseconds: 200),
RouteTransitionsBuilder transitionBuilder,
bool useRootNavigator = true,
RouteSettings routeSettings,
});
Future<T> defaultDialog<T>({
String title = "Alert",
Widget content,
VoidCallback onConfirm,
VoidCallback onCancel,
VoidCallback onCustom,
Color cancelTextColor,
Color confirmTextColor,
String textConfirm,
String textCancel,
String textCustom,
Widget confirm,
Widget cancel,
Widget custom,
Color backgroundColor,
Color buttonColor,
String middleText = "Dialog made in 3 lines of code",
double radius = 20.0,
List<Widget> actions,
});
Future<T> bottomSheet<T>(
Widget bottomsheet, {
Color backgroundColor,
double elevation,
ShapeBorder shape,
Clip clipBehavior,
Color barrierColor,
bool ignoreSafeArea,
bool isScrollControlled = false,
bool useRootNavigator = false,
bool isDismissible = true,
bool enableDrag = true,
});
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});
void snackbar(title, message,
{Color colorText,
Duration duration,
/// with instantInit = false you can put Get.snackbar on initState
bool instantInit = true,
SnackPosition snackPosition,
Widget titleText,
Widget messageText,
Widget icon,
bool shouldIconPulse,
double maxWidth,
EdgeInsets margin,
EdgeInsets padding,
double borderRadius,
Color borderColor,
double borderWidth,
Color backgroundColor,
Color leftBarIndicatorColor,
List<BoxShadow> boxShadows,
Gradient backgroundGradient,
FlatButton mainButton,
OnTap onTap,
bool isDismissible,
bool showProgressIndicator,
SnackDismissDirection dismissDirection,
AnimationController progressIndicatorController,
Color progressIndicatorBackgroundColor,
Animation<Color> progressIndicatorValueColor,
SnackStyle snackStyle,
Curve forwardAnimationCurve,
Curve reverseAnimationCurve,
Duration animationDuration,
double barBlur,
double overlayBlur,
Color overlayColor,
Form userInputForm});
/// INSTANCE MANAGER
GetMaterialController getController;
changeTheme(ThemeData theme);
changeThemeMode(ThemeMode themeMode);
GlobalKey<NavigatorState> addKey(GlobalKey<NavigatorState> newKey);
GlobalKey<NavigatorState> key;
GlobalKey<NavigatorState> nestedKey(int key);
GlobalKey<NavigatorState> global(int k);
//////////// INSTANCE MANAGER
setParameter(Map<String, String> param);
/// give current arguments
Object get arguments;
/// give current arguments
Map<String, String> get parameters;
/// give name from current route
String get currentRoute;
/// give name from previous route
String get previousRoute;
/// check if snackbar is open
bool get isSnackbarOpen;
/// check if dialog is open
bool get isDialogOpen;
/// check if bottomsheet is open
bool get isBottomSheetOpen;
/// check a raw current route
Route<dynamic> get rawRoute;
/// give access to currentContext
BuildContext get context;
/// give access to current Overlay Context
BuildContext get overlayContext;
/// give access to Theme.of(context)
ThemeData get theme;
/// give access to TextTheme.of(context)
TextTheme get textTheme;
/// give access to Mediaquery.of(context)
MediaQueryData get mediaQuery;
/// Check if dark mode theme is enable
bool get isDarkMode;
/// Check if dark mode theme is enable on platform on android Q+
bool get isPlatformDarkMode;
/// give access to Theme.of(context).iconTheme.color
Color get iconColor;
/// give access to Focus.of(context).iconTheme.color
FocusNode get focusScope;
/// give access to MediaQuery.of(context).size.height
double get height;
/// give access to MediaQuery.of(context).size.width
double get width;
}
... ...
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:get/get.dart';
import 'package:get/src/get_interface.dart';
import 'bottomsheet/bottomsheet.dart';
import 'platform/platform.dart';
import 'root/root_controller.dart';
import 'root/smart_management.dart';
import 'routes/bindings_interface.dart';
import 'routes/default_route.dart';
import 'routes/observers/route_observer.dart';
import 'routes/transitions_type.dart';
import 'rx/rx_interface.dart';
import 'snackbar/snack.dart';
///Use Get.to instead of Navigator.push, Get.off instead of Navigator.pushReplacement,
///Get.offAll instead of Navigator.pushAndRemoveUntil. For named routes just add "named"
///after them. Example: Get.toNamed, Get.offNamed, and Get.AllNamed.
///To return to the previous screen, use Get.back().
///Use to instead of Navigator.push, off instead of Navigator.pushReplacement,
///offAll instead of Navigator.pushAndRemoveUntil. For named routes just add "named"
///after them. Example: toNamed, offNamed, and AllNamed.
///To return to the previous screen, use back().
///No need to pass any context to Get, just put the name of the route inside
///the parentheses and the magic will occur.
class Get {
factory Get() {
if (_get == null) _get = Get._();
return _get;
}
bool _enableLog = true;
bool _defaultPopGesture = GetPlatform.isIOS;
bool _defaultOpaqueRoute = true;
Transition _defaultTransition =
class GetImpl implements GetService {
bool defaultPopGesture = GetPlatform.isIOS;
bool defaultOpaqueRoute = true;
Transition defaultTransition =
(GetPlatform.isIOS ? Transition.cupertino : Transition.fade);
Duration _defaultDurationTransition = Duration(milliseconds: 400);
bool _defaultGlobalState = true;
RouteSettings _settings;
SmartManagement smartManagement = SmartManagement.full;
///Use Get.to instead of Navigator.push, Get.off instead of Navigator.pushReplacement,
///Get.offAll instead of Navigator.pushAndRemoveUntil. For named routes just add "named"
///after them. Example: Get.toNamed, Get.offNamed, and Get.AllNamed.
///To return to the previous screen, use Get.back().
Duration defaultDurationTransition = Duration(milliseconds: 400);
bool defaultGlobalState = true;
RouteSettings settings;
///Use to instead of Navigator.push, off instead of Navigator.pushReplacement,
///offAll instead of Navigator.pushAndRemoveUntil. For named routes just add "named"
///after them. Example: toNamed, offNamed, and AllNamed.
///To return to the previous screen, use back().
///No need to pass any context to Get, just put the name of the route inside
///the parentheses and the magic will occur.
Get._();
static Get _get;
GlobalKey<NavigatorState> _key;
/// It replaces Navigator.push, but needs no context, and it doesn't have the Navigator.push
/// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
/// of rebuilding every app after a route, use opaque = true as the parameter.
static Future<T> to<T>(Widget page,
Future<T> to<T>(Widget page,
{bool opaque,
Transition transition,
Duration duration,
... ... @@ -58,108 +45,104 @@ class Get {
Object arguments,
Bindings binding,
bool popGesture}) {
return _get.global(id).currentState.push(GetRouteBase(
return global(id).currentState.push(GetRouteBase(
opaque: opaque ?? true,
page: page,
settings: RouteSettings(
name: '/' + page.toString().toLowerCase(), arguments: arguments),
popGesture: popGesture ?? _get._defaultPopGesture,
transition: transition ?? _get._defaultTransition,
popGesture: popGesture ?? defaultPopGesture,
transition: transition ?? defaultTransition,
fullscreenDialog: fullscreenDialog,
binding: binding,
transitionDuration: duration ?? _get._defaultDurationTransition));
transitionDuration: duration ?? defaultDurationTransition));
}
/// It replaces Navigator.pushNamed, but needs no context, and it doesn't have the Navigator.pushNamed
/// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
/// of rebuilding every app after a route, use opaque = true as the parameter.
static Future<T> toNamed<T>(String page, {Object arguments, int id}) {
Future<T> toNamed<T>(String page, {Object arguments, int id}) {
// if (key.currentState.mounted) // add this if appear problems on future with route navigate
// when widget don't mounted
return _get.global(id).currentState.pushNamed(page, arguments: arguments);
return global(id).currentState.pushNamed(page, arguments: arguments);
}
/// It replaces Navigator.pushReplacementNamed, but needs no context.
static Future<T> offNamed<T>(String page, {Object arguments, int id}) {
Future<T> offNamed<T>(String page, {Object arguments, int id}) {
// if (key.currentState.mounted) // add this if appear problems on future with route navigate
// when widget don't mounted
return _get
.global(id)
return global(id)
.currentState
.pushReplacementNamed(page, arguments: arguments);
}
/// It replaces Navigator.popUntil, but needs no context.
static void until(RoutePredicate predicate, {int id}) {
void until(RoutePredicate predicate, {int id}) {
// if (key.currentState.mounted) // add this if appear problems on future with route navigate
// when widget don't mounted
return _get.global(id).currentState.popUntil(predicate);
return global(id).currentState.popUntil(predicate);
}
/// It replaces Navigator.pushAndRemoveUntil, but needs no context.
static Future<T> offUntil<T>(Route<T> page, RoutePredicate predicate,
{int id}) {
Future<T> offUntil<T>(Route<T> page, RoutePredicate predicate, {int id}) {
// if (key.currentState.mounted) // add this if appear problems on future with route navigate
// when widget don't mounted
return _get.global(id).currentState.pushAndRemoveUntil(page, predicate);
return global(id).currentState.pushAndRemoveUntil(page, predicate);
}
/// It replaces Navigator.pushNamedAndRemoveUntil, but needs no context.
static Future<T> offNamedUntil<T>(String page, RoutePredicate predicate,
Future<T> offNamedUntil<T>(String page, RoutePredicate predicate,
{int id, Object arguments}) {
return _get
.global(id)
return global(id)
.currentState
.pushNamedAndRemoveUntil(page, predicate, arguments: arguments);
}
/// It replaces Navigator.popAndPushNamed, but needs no context.
static Future<T> offAndToNamed<T>(String page,
Future<T> offAndToNamed<T>(String page,
{Object arguments, int id, dynamic result}) {
return _get
.global(id)
return global(id)
.currentState
.popAndPushNamed(page, arguments: arguments, result: result);
}
/// It replaces Navigator.removeRoute, but needs no context.
static void removeRoute(Route<dynamic> route, {int id}) {
return _get.global(id).currentState.removeRoute(route);
void removeRoute(Route<dynamic> route, {int id}) {
return global(id).currentState.removeRoute(route);
}
/// It replaces Navigator.pushNamedAndRemoveUntil, but needs no context.
static Future<T> offAllNamed<T>(String newRouteName,
Future<T> offAllNamed<T>(String newRouteName,
{RoutePredicate predicate, Object arguments, int id}) {
var route = (Route<dynamic> rota) => false;
return _get.global(id).currentState.pushNamedAndRemoveUntil(
return global(id).currentState.pushNamedAndRemoveUntil(
newRouteName, predicate ?? route,
arguments: arguments);
}
static bool get isOverlaysOpen =>
bool get isOverlaysOpen =>
(isSnackbarOpen || isDialogOpen || isBottomSheetOpen);
static bool get isOverlaysClosed =>
(!Get.isSnackbarOpen && !Get.isDialogOpen && !Get.isBottomSheetOpen);
bool get isOverlaysClosed =>
(!isSnackbarOpen && !isDialogOpen && !isBottomSheetOpen);
/// It replaces Navigator.pop, but needs no context.
static void back({dynamic result, bool closeOverlays = false, int id}) {
void back({dynamic result, bool closeOverlays = false, int id}) {
if (closeOverlays && isOverlaysOpen) {
navigator.popUntil((route) {
return (isOverlaysClosed);
});
}
_get.global(id).currentState.pop(result);
global(id).currentState.pop(result);
}
/// It will close as many screens as you define. Times must be> 0;
static void close(int times, [int id]) {
void close(int times, [int id]) {
if ((times == null) || (times < 1)) {
times = 1;
}
int count = 0;
void back = _get.global(id).currentState.popUntil((route) {
void back = global(id).currentState.popUntil((route) {
return count++ == times;
});
return back;
... ... @@ -168,7 +151,7 @@ class Get {
/// It replaces Navigator.pushReplacement, but needs no context, and it doesn't have the Navigator.pushReplacement
/// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
/// of rebuilding every app after a route, use opaque = true as the parameter.
static Future<T> off<T>(Widget page,
Future<T> off<T>(Widget page,
{bool opaque = false,
Transition transition,
bool popGesture,
... ... @@ -177,20 +160,20 @@ class Get {
Bindings binding,
bool fullscreenDialog = false,
Duration duration}) {
return _get.global(id).currentState.pushReplacement(GetRouteBase(
return global(id).currentState.pushReplacement(GetRouteBase(
opaque: opaque ?? true,
page: page,
binding: binding,
settings: RouteSettings(
name: '/' + page.toString().toLowerCase(), arguments: arguments),
fullscreenDialog: fullscreenDialog,
popGesture: popGesture ?? _get._defaultPopGesture,
transition: transition ?? _get._defaultTransition,
transitionDuration: duration ?? _get._defaultDurationTransition));
popGesture: popGesture ?? defaultPopGesture,
transition: transition ?? defaultTransition,
transitionDuration: duration ?? defaultDurationTransition));
}
/// It replaces Navigator.pushAndRemoveUntil, but needs no context
static Future<T> offAll<T>(Widget page,
Future<T> offAll<T>(Widget page,
{RoutePredicate predicate,
bool opaque = false,
bool popGesture,
... ... @@ -201,22 +184,22 @@ class Get {
Transition transition}) {
var route = (Route<dynamic> rota) => false;
return _get.global(id).currentState.pushAndRemoveUntil(
return global(id).currentState.pushAndRemoveUntil(
GetRouteBase(
opaque: opaque ?? true,
popGesture: popGesture ?? _get._defaultPopGesture,
popGesture: popGesture ?? defaultPopGesture,
page: page,
binding: binding,
settings: RouteSettings(
name: '/' + page.toString().toLowerCase(), arguments: arguments),
fullscreenDialog: fullscreenDialog,
transition: transition ?? _get._defaultTransition,
transition: transition ?? defaultTransition,
),
predicate ?? route);
}
/// Show a dialog
static Future<T> dialog<T>(
Future<T> dialog<T>(
Widget child, {
bool barrierDismissible = true,
bool useRootNavigator = true,
... ... @@ -234,7 +217,7 @@ class Get {
}
/// Api from showGeneralDialog with no context
static Future<T> generalDialog<T>({
Future<T> generalDialog<T>({
@required RoutePageBuilder pageBuilder,
String barrierLabel = "Dismiss",
bool barrierDismissible = true,
... ... @@ -257,7 +240,7 @@ class Get {
);
}
static Future<T> defaultDialog<T>({
Future<T> defaultDialog<T>({
String title = "Alert",
Widget content,
VoidCallback onConfirm,
... ... @@ -289,7 +272,7 @@ class Get {
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onPressed: () {
onCancel?.call();
Get.back();
back();
},
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: Text(
... ... @@ -298,7 +281,7 @@ class Get {
),
shape: RoundedRectangleBorder(
side: BorderSide(
color: buttonColor ?? Get.theme.accentColor,
color: buttonColor ?? theme.accentColor,
width: 2,
style: BorderStyle.solid),
borderRadius: BorderRadius.circular(100)),
... ... @@ -311,7 +294,7 @@ class Get {
if (leanConfirm) {
actions.add(FlatButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
color: buttonColor ?? Get.theme.accentColor,
color: buttonColor ?? theme.accentColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100)),
child: Text(
... ... @@ -323,10 +306,10 @@ class Get {
}));
}
}
return Get.dialog(AlertDialog(
return dialog(AlertDialog(
titlePadding: EdgeInsets.all(8),
contentPadding: EdgeInsets.all(8),
backgroundColor: backgroundColor ?? Get.theme.dialogBackgroundColor,
backgroundColor: backgroundColor ?? theme.dialogBackgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(radius))),
title: Text(title, textAlign: TextAlign.center),
... ... @@ -353,7 +336,7 @@ class Get {
));
}
static Future<T> bottomSheet<T>(
Future<T> bottomSheet<T>(
Widget bottomsheet, {
Color backgroundColor,
double elevation,
... ... @@ -375,10 +358,10 @@ class Get {
return Navigator.of(overlayContext, rootNavigator: useRootNavigator)
.push(GetModalBottomSheetRoute<T>(
builder: (_) => bottomsheet,
theme: Theme.of(Get.key.currentContext, shadowThemeOnly: true),
theme: Theme.of(key.currentContext, shadowThemeOnly: true),
isScrollControlled: isScrollControlled,
barrierLabel: MaterialLocalizations.of(Get.key.currentContext)
.modalBarrierDismissLabel,
barrierLabel:
MaterialLocalizations.of(key.currentContext).modalBarrierDismissLabel,
backgroundColor: backgroundColor ?? Colors.transparent,
elevation: elevation,
shape: shape,
... ... @@ -391,7 +374,7 @@ class Get {
));
}
static void rawSnackbar(
void rawSnackbar(
{String title,
String message,
Widget titleText,
... ... @@ -473,12 +456,12 @@ class Get {
}
}
static void snackbar(title, message,
void snackbar(title, message,
{Color colorText,
Duration duration,
/// with instantInit = false you can put Get.snackbar on initState
bool instantInit = false,
/// with instantInit = false you can put snackbar on initState
bool instantInit = true,
SnackPosition snackPosition,
Widget titleText,
Widget messageText,
... ... @@ -563,7 +546,7 @@ class Get {
if (instantInit) {
getBar.show();
} else {
Get()._routing.isSnackbar = true;
_routing.isSnackbar = true;
SchedulerBinding.instance.addPostFrameCallback((_) {
getBar.show();
});
... ... @@ -571,7 +554,7 @@ class Get {
}
/// change default config of Get
Get.config(
config(
{bool enableLog,
bool defaultPopGesture,
bool defaultOpaqueRoute,
... ... @@ -579,57 +562,49 @@ class Get {
bool defaultGlobalState,
Transition defaultTransition}) {
if (enableLog != null) {
Get()._enableLog = enableLog;
enableLog = enableLog;
}
if (defaultPopGesture != null) {
Get()._defaultPopGesture = defaultPopGesture;
defaultPopGesture = defaultPopGesture;
}
if (defaultOpaqueRoute != null) {
Get()._defaultOpaqueRoute = defaultOpaqueRoute;
defaultOpaqueRoute = defaultOpaqueRoute;
}
if (defaultTransition != null) {
Get()._defaultTransition = defaultTransition;
defaultTransition = defaultTransition;
}
if (defaultDurationTransition != null) {
Get()._defaultDurationTransition = defaultDurationTransition;
defaultDurationTransition = defaultDurationTransition;
}
if (defaultGlobalState != null) {
Get()._defaultGlobalState = defaultGlobalState;
defaultGlobalState = defaultGlobalState;
}
}
GetMaterialController _getController = GetMaterialController();
GetMaterialController get getController => _getController;
GetMaterialController getController = GetMaterialController();
Get.changeTheme(ThemeData theme) {
Get()._getController.setTheme(theme);
changeTheme(ThemeData theme) {
getController.setTheme(theme);
}
Get.changeThemeMode(ThemeMode themeMode) {
Get()._getController.setThemeMode(themeMode);
changeThemeMode(ThemeMode themeMode) {
getController.setThemeMode(themeMode);
}
static GlobalKey<NavigatorState> addKey(GlobalKey<NavigatorState> newKey) {
Get()._key = newKey;
return Get()._key;
GlobalKey<NavigatorState> addKey(GlobalKey<NavigatorState> newKey) {
key = newKey;
return key;
}
static GlobalKey<NavigatorState> get key {
// _get start empty, is mandatory key be static to prevent errors like "key was called null"
if (Get()._key == null) {
Get()._key = GlobalKey<NavigatorState>();
}
return Get()._key;
}
GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
Map<int, GlobalKey<NavigatorState>> _keys = {};
UniqueKey mKey = UniqueKey();
static GlobalKey<NavigatorState> nestedKey(int key) {
Get()._keys.putIfAbsent(key, () => GlobalKey<NavigatorState>());
return Get()._keys[key];
GlobalKey<NavigatorState> nestedKey(int key) {
_keys.putIfAbsent(key, () => GlobalKey<NavigatorState>());
return _keys[key];
}
GlobalKey<NavigatorState> global(int k) {
... ... @@ -642,366 +617,94 @@ class Get {
return _keys[k];
}
//////////// INSTANCE MANAGER
Map<dynamic, dynamic> _singl = {};
Map<dynamic, _FcBuilderFunc> _factory = {};
static void lazyPut<S>(_FcBuilderFunc builder, {String tag}) {
String key = _getKey(S, tag);
Get()._factory.putIfAbsent(key, () => builder);
}
static Future<S> putAsync<S>(_FcBuilderFuncAsync<S> builder,
{String tag}) async {
WidgetsFlutterBinding.ensureInitialized();
return Get.put<S>(await builder(), tag: tag);
}
/// Inject class on Get Instance Manager
static S put<S>(
S dependency, {
String tag,
bool permanent = false,
bool overrideAbstract = false,
_FcBuilderFunc<S> builder,
}) {
_insert(
isSingleton: true,
replace: overrideAbstract,
//?? (("$S" == "${dependency.runtimeType}") == false),
name: tag,
permanent: permanent,
builder: builder ?? (() => dependency));
return find<S>(tag: tag);
}
/// 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,
bool permanent = false,
_FcBuilderFunc<S> builder,
}) {
assert(builder != null);
String key = _getKey(S, name);
if (replace) {
Get()._singl[key] = _FcBuilder<S>(isSingleton, builder, permanent);
} else {
Get()._singl.putIfAbsent(
key, () => _FcBuilder<S>(isSingleton, builder, permanent));
}
}
Map<String, String> routesKey = {};
void removeDependencyByRoute(String routeName) async {
List<String> keysToRemove = [];
Get().routesKey.forEach((key, value) {
// if (value == routeName && value != null) {
if (value == routeName) {
keysToRemove.add(key);
}
});
keysToRemove.forEach((element) async {
await Get.delete(key: element);
});
keysToRemove.forEach((element) {
Get().routesKey?.remove(element);
});
keysToRemove.clear();
}
static bool isRouteDependecyNull<S>({String name}) {
return (Get().routesKey[_getKey(S, name)] == null);
}
static bool isDependencyInit<S>({String name}) {
String key = _getKey(S, name);
return Get().routesKey.containsKey(key);
}
void registerRouteInstance<S>({String tag}) {
// print("Register route [$S] as ${Get.currentRoute}");
Get().routesKey.putIfAbsent(_getKey(S, tag), () => Get.currentRoute);
}
static S findByType<S>(Type type, {String tag}) {
String key = _getKey(type, tag);
return Get()._singl[key].getSependency();
}
void initController<S>({String tag}) {
String key = _getKey(S, tag);
final i = Get()._singl[key].getSependency();
if (i is DisposableInterface) {
i.onStart();
if (isLogEnable) print('[GET] $key has been initialized');
}
}
/// Find a instance from required class
static S find<S>({String tag, _FcBuilderFunc<S> instance}) {
String key = _getKey(S, tag);
bool callInit = false;
if (Get.isRegistred<S>(tag: tag)) {
if (!isDependencyInit<S>() &&
Get().smartManagement != SmartManagement.onlyBuilder) {
Get().registerRouteInstance<S>(tag: tag);
callInit = true;
}
_FcBuilder builder = Get()._singl[key];
if (builder == null) {
if (tag == null) {
throw "class ${S.toString()} is not register";
} else {
throw "class ${S.toString()} with tag '$tag' is not register";
}
}
if (callInit) {
Get().initController<S>(tag: tag);
}
return Get()._singl[key].getSependency();
} else {
if (!Get()._factory.containsKey(key))
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[key].call() as S);
if (!isDependencyInit<S>() &&
Get().smartManagement != SmartManagement.onlyBuilder) {
Get().registerRouteInstance<S>(tag: tag);
callInit = true;
}
if (Get().smartManagement != SmartManagement.keepFactory) {
Get()._factory.remove(key);
}
if (callInit) {
Get().initController<S>(tag: tag);
}
return _value;
}
}
/// Remove dependency of [S] on dependency abstraction. For concrete class use Get.delete
static void remove<S>({String tag}) {
String key = _getKey(S, tag);
_FcBuilder builder = Get()._singl[key];
final i = builder.dependency;
if (i is DisposableInterface || i is GetController) {
i.onClose();
if (isLogEnable) print('[GET] onClose of $key called');
}
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(
{bool clearFactory = true, bool clearRouteBindings = true}) {
if (clearFactory) Get()._factory.clear();
if (clearRouteBindings) Get().routesKey.clear();
Get()._singl.clear();
return true;
}
/// Delete class instance on [S] and clean memory
static Future<bool> delete<S>({String tag, String key}) async {
String newKey;
if (key == null) {
newKey = _getKey(S, tag);
} else {
newKey = key;
}
if (!Get()._singl.containsKey(newKey)) {
print('Instance $newKey not found');
return false;
}
_FcBuilder builder = Get()._singl[newKey];
if (builder.permanent) {
(key == null)
? print(
'[GET] [$newKey] has been marked as permanent, SmartManagement is not authorized to delete it.')
: print(
'[GET] [$newKey] has been marked as permanent, SmartManagement is not authorized to delete it.');
return false;
}
final i = builder.dependency;
if (i is DisposableInterface || i is GetController) {
await i.onClose();
if (isLogEnable) print('[GET] onClose of $newKey called');
}
Get()._singl.removeWhere((oldkey, value) => (oldkey == newKey));
if (Get()._singl.containsKey(newKey)) {
print('[GET] error on remove object $newKey');
} else {
if (isLogEnable) print('[GET] $newKey deleted from memory');
}
// Get().routesKey?.remove(key);
return true;
}
/// check if instance is registred
static bool isRegistred<S>({String tag}) =>
Get()._singl.containsKey(_getKey(S, tag));
static bool isPrepared<S>({String tag}) =>
Get()._factory.containsKey(_getKey(S, tag));
/// give access to Routing API from GetObserver
static Routing get routing => Get()._routing;
Routing get routing => _routing;
static RouteSettings get routeSettings => Get()._settings;
RouteSettings get routeSettings => settings;
Routing _routing = Routing();
Map<String, String> _parameters = {};
Get.setParameter(Map<String, String> param) {
Get()._parameters = param;
setParameter(Map<String, String> param) {
_parameters = param;
}
Get.setRouting(Routing rt) {
Get()._routing = rt;
setRouting(Routing rt) {
_routing = rt;
}
Get.setSettings(RouteSettings settings) {
Get()._settings = settings;
setSettings(RouteSettings settings) {
settings = settings;
}
/// give current arguments
static Object get arguments => Get()._routing.args;
Object get arguments => _routing.args;
/// give current arguments
static Map<String, String> get parameters => Get()._parameters;
Map<String, String> get parameters => _parameters;
/// give name from current route
static get currentRoute => Get()._routing.current;
get currentRoute => _routing.current;
/// give name from previous route
static get previousRoute => Get()._routing.previous;
get previousRoute => _routing.previous;
/// check if snackbar is open
static bool get isSnackbarOpen => Get()._routing.isSnackbar;
bool get isSnackbarOpen => _routing.isSnackbar;
/// check if dialog is open
static bool get isDialogOpen => Get()._routing.isDialog;
bool get isDialogOpen => _routing.isDialog;
/// check if bottomsheet is open
static bool get isBottomSheetOpen => Get()._routing.isBottomSheet;
bool get isBottomSheetOpen => _routing.isBottomSheet;
/// check a raw current route
static Route<dynamic> get rawRoute => Get()._routing.route;
/// check if log is enable
static bool get isLogEnable => Get()._enableLog;
/// default duration of transition animation
/// default duration work only API 2.0
static Duration get defaultDurationTransition =>
Get()._defaultDurationTransition;
/// give global state of all GetState by default
static bool get defaultGlobalState => Get()._defaultGlobalState;
Route<dynamic> get rawRoute => _routing.route;
/// check if popGesture is enable
static bool get isPopGestureEnable => Get()._defaultPopGesture;
bool get isPopGestureEnable => defaultPopGesture;
/// check if default opaque route is enable
static bool get isOpaqueRouteDefault => Get()._defaultOpaqueRoute;
static Transition get defaultTransition => Get()._defaultTransition;
bool get isOpaqueRouteDefault => defaultOpaqueRoute;
/// give access to currentContext
static BuildContext get context => key.currentContext;
BuildContext get context => key.currentContext;
/// give access to current Overlay Context
static BuildContext get overlayContext => key.currentState.overlay.context;
BuildContext get overlayContext => key.currentState.overlay.context;
/// give access to Theme.of(context)
static ThemeData get theme => Theme.of(context);
ThemeData get theme => Theme.of(context);
/// give access to TextTheme.of(context)
static TextTheme get textTheme => Theme.of(context).textTheme;
TextTheme get textTheme => Theme.of(context).textTheme;
/// give access to Mediaquery.of(context)
static MediaQueryData get mediaQuery => MediaQuery.of(context);
MediaQueryData get mediaQuery => MediaQuery.of(context);
/// Check if dark mode theme is enable
static get isDarkMode => (theme.brightness == Brightness.dark);
get isDarkMode => (theme.brightness == Brightness.dark);
/// Check if dark mode theme is enable on platform on android Q+
static get isPlatformDarkMode =>
(mediaQuery.platformBrightness == Brightness.dark);
get isPlatformDarkMode => (mediaQuery.platformBrightness == Brightness.dark);
/// give access to Theme.of(context).iconTheme.color
static Color get iconColor => Theme.of(context).iconTheme.color;
Color get iconColor => Theme.of(context).iconTheme.color;
/// give access to Focus.of(context).iconTheme.color
static FocusScopeNode get focusScope => FocusScope.of(context);
/// give access to FocusScope.of(context)
FocusNode get focusScope => FocusManager.instance.primaryFocus;
/// give access to MediaQuery.of(context).size.height
static double get height => MediaQuery.of(context).size.height;
/// give access to Immutable MediaQuery.of(context).size.height
double get height => MediaQuery.of(context).size.height;
/// give access to MediaQuery.of(context).size.width
static double get width => MediaQuery.of(context).size.width;
/// give access to Immutable MediaQuery.of(context).size.width
double get width => MediaQuery.of(context).size.width;
}
// ignore: non_constant_identifier_names
final Get = GetImpl();
/// 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;
bool permanent = false;
_FcBuilder(this.isSingleton, this.builderFunc, this.permanent);
S getSependency() {
if (isSingleton) {
if (dependency == null) {
dependency = builderFunc() as S;
}
return dependency;
} else {
return builderFunc() as S;
}
}
}
typedef _FcBuilderFunc<S> = S Function();
typedef _FcBuilderFuncAsync<S> = Future<S> Function();
... ...
... ... @@ -2,6 +2,7 @@ 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 '../get_instance.dart';
import 'root_controller.dart';
import 'smart_management.dart';
... ... @@ -109,7 +110,7 @@ class GetMaterialApp extends StatelessWidget {
/// 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.
var parsedString = Get().getController.parse.split(
var parsedString = Get.getController.parse.split(
(settings.name == '' || settings.name == null)
? (initialRoute ?? '/')
: settings.name);
... ... @@ -123,7 +124,7 @@ class GetMaterialApp extends StatelessWidget {
Map<String, GetRoute> newNamedRoutes = {};
namedRoutes.forEach((key, value) {
String newName = Get().getController.parse.split(key).route;
String newName = Get.getController.parse.split(key).route;
newNamedRoutes.addAll({newName: value});
});
... ... @@ -179,21 +180,21 @@ class GetMaterialApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetBuilder<GetMaterialController>(
init: Get().getController,
init: Get.getController,
dispose: (d) {
onDispose?.call();
},
initState: (i) {
initialBinding?.dependencies();
Get().smartManagement = smartManagement;
GetConfig.smartManagement = smartManagement;
onInit?.call();
if (namedRoutes != null) {
namedRoutes.forEach((key, value) {
Get().getController.parse.addRoute(key);
Get.getController.parse.addRoute(key);
});
}
Get.config(
enableLog: enableLog ?? Get.isLogEnable,
enableLog: enableLog ?? GetConfig.isLogEnable,
defaultTransition: defaultTransition ?? Get.defaultTransition,
defaultOpaqueRoute: opaqueRoute ?? Get.isOpaqueRouteDefault,
defaultPopGesture: popGesture ?? Get.isPopGestureEnable,
... ...
import 'package:flutter/widgets.dart';
import 'package:get/src/root/smart_management.dart';
import '../../get_instance.dart';
import '../../get_main.dart';
class Routing {
... ... @@ -44,13 +45,17 @@ class GetObserver extends NavigatorObserver {
@override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
if ('${route?.settings?.name}' == 'snackbar') {
if (Get.isLogEnable) print("[OPEN SNACKBAR] ${route?.settings?.name}");
if (GetConfig.isLogEnable)
print("[OPEN SNACKBAR] ${route?.settings?.name}");
} else if ('${route?.settings?.name}' == 'bottomsheet') {
if (Get.isLogEnable) print("[OPEN BOTTOMSHEET] ${route?.settings?.name}");
if (GetConfig.isLogEnable)
print("[OPEN BOTTOMSHEET] ${route?.settings?.name}");
} else if ('${route?.settings?.name}' == 'dialog') {
if (Get.isLogEnable) print("[OPEN DIALOG] ${route?.settings?.name}");
if (GetConfig.isLogEnable)
print("[OPEN DIALOG] ${route?.settings?.name}");
} else {
if (Get.isLogEnable) print("[GOING TO ROUTE] ${route?.settings?.name}");
if (GetConfig.isLogEnable)
print("[GOING TO ROUTE] ${route?.settings?.name}");
}
isSnackbar = '${route?.settings?.name}' == 'snackbar';
... ... @@ -76,6 +81,7 @@ class GetObserver extends NavigatorObserver {
if (routing != null) {
routing(routeSend);
}
GetConfig.currentRoute = current;
Get.setRouting(routeSend);
}
... ... @@ -84,18 +90,20 @@ class GetObserver extends NavigatorObserver {
super.didPop(route, previousRoute);
if ('${route?.settings?.name}' == 'snackbar') {
if (Get.isLogEnable) print("[CLOSE SNACKBAR] ${route?.settings?.name}");
if (GetConfig.isLogEnable)
print("[CLOSE SNACKBAR] ${route?.settings?.name}");
} else if ('${route?.settings?.name}' == 'bottomsheet') {
if (Get.isLogEnable)
if (GetConfig.isLogEnable)
print("[CLOSE BOTTOMSHEET] ${route?.settings?.name}");
} else if ('${route?.settings?.name}' == 'dialog') {
if (Get.isLogEnable) print("[CLOSE DIALOG] ${route?.settings?.name}");
if (GetConfig.isLogEnable)
print("[CLOSE DIALOG] ${route?.settings?.name}");
} else {
if (Get.isLogEnable) print("[BACK ROUTE] ${route?.settings?.name}");
if (GetConfig.isLogEnable) print("[BACK ROUTE] ${route?.settings?.name}");
}
if (Get().smartManagement != SmartManagement.onlyBuilder) {
Get().removeDependencyByRoute("${route?.settings?.name}");
if (GetConfig.smartManagement != SmartManagement.onlyBuilder) {
GetInstance().removeDependencyByRoute("${route?.settings?.name}");
}
isSnackbar = false;
... ... @@ -122,17 +130,19 @@ class GetObserver extends NavigatorObserver {
if (routing != null) {
routing(routeSend);
}
GetConfig.currentRoute = current;
Get.setRouting(routeSend);
}
@override
void didReplace({Route newRoute, Route oldRoute}) {
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
if (Get.isLogEnable) print("[REPLACE ROUTE] ${oldRoute?.settings?.name}");
if (Get.isLogEnable) print("[NEW ROUTE] ${newRoute?.settings?.name}");
if (GetConfig.isLogEnable)
print("[REPLACE ROUTE] ${oldRoute?.settings?.name}");
if (GetConfig.isLogEnable) print("[NEW ROUTE] ${newRoute?.settings?.name}");
if (Get().smartManagement == SmartManagement.full) {
Get().removeDependencyByRoute("${oldRoute?.settings?.name}");
if (GetConfig.smartManagement == SmartManagement.full) {
GetInstance().removeDependencyByRoute("${oldRoute?.settings?.name}");
}
isSnackbar = false;
... ... @@ -155,16 +165,18 @@ class GetObserver extends NavigatorObserver {
if (routing != null) {
routing(routeSend);
}
GetConfig.currentRoute = current;
Get.setRouting(routeSend);
}
@override
void didRemove(Route route, Route previousRoute) {
super.didRemove(route, previousRoute);
if (Get.isLogEnable) print("[REMOVING ROUTE] ${route?.settings?.name}");
if (GetConfig.isLogEnable)
print("[REMOVING ROUTE] ${route?.settings?.name}");
if (Get().smartManagement == SmartManagement.full) {
Get().removeDependencyByRoute("${route?.settings?.name}");
if (GetConfig.smartManagement == SmartManagement.full) {
GetInstance().removeDependencyByRoute("${route?.settings?.name}");
}
final routeSend = Routing(
... ... @@ -184,6 +196,7 @@ class GetObserver extends NavigatorObserver {
if (routing != null) {
routing(routeSend);
}
GetConfig.currentRoute = current;
Get.setRouting(routeSend);
}
}
... ...
import 'package:flutter/widgets.dart';
import 'package:get/src/get_main.dart';
import 'package:get/src/root/smart_management.dart';
import '../get_instance.dart';
import 'rx_impl.dart';
import 'rx_interface.dart';
... ... @@ -25,35 +25,32 @@ class GetX<T extends DisposableInterface> extends StatefulWidget {
this.init,
// this.streamController
});
_GetXState<T> createState() => _GetXState<T>();
GetImplXState<T> createState() => GetImplXState<T>();
}
class _GetXState<T extends DisposableInterface> extends State<GetX<T>> {
class GetImplXState<T extends DisposableInterface> extends State<GetX<T>> {
RxInterface _observer;
T controller;
bool isCreator = false;
_GetXState() {
_observer = Rx();
}
@override
void initState() {
bool isPrepared = Get.isPrepared<T>();
bool isRegistred = Get.isRegistred<T>();
_observer = Rx();
bool isPrepared = GetInstance().isPrepared<T>();
bool isRegistred = GetInstance().isRegistred<T>();
if (widget.global) {
if (isPrepared) {
if (Get().smartManagement != SmartManagement.keepFactory) {
if (GetConfig.smartManagement != SmartManagement.keepFactory) {
isCreator = true;
}
controller = Get.find<T>();
controller = GetInstance().find<T>();
} else if (isRegistred) {
controller = Get.find<T>();
controller = GetInstance().find<T>();
isCreator = false;
} else {
controller = widget.init;
isCreator = true;
Get.put<T>(controller);
GetInstance().put<T>(controller);
}
} else {
controller = widget.init;
... ... @@ -61,7 +58,7 @@ class _GetXState<T extends DisposableInterface> extends State<GetX<T>> {
controller?.onStart();
}
if (widget.initState != null) widget.initState(this);
if (isCreator && Get().smartManagement == SmartManagement.onlyBuilder) {
if (isCreator && GetConfig.smartManagement == SmartManagement.onlyBuilder) {
controller?.onStart();
}
_observer.subject.stream.listen((data) => setState(() {}));
... ... @@ -72,8 +69,8 @@ class _GetXState<T extends DisposableInterface> extends State<GetX<T>> {
void dispose() {
if (widget.dispose != null) widget.dispose(this);
if (isCreator || widget.assignId) {
if (widget.autoRemove && Get.isRegistred<T>()) {
Get.delete<T>();
if (widget.autoRemove && GetInstance().isRegistred<T>()) {
GetInstance().delete<T>();
}
}
... ... @@ -83,12 +80,14 @@ class _GetXState<T extends DisposableInterface> extends State<GetX<T>> {
super.dispose();
}
@override
Widget build(BuildContext context) {
Widget get notifyChilds {
final observer = getObs;
getObs = this._observer;
getObs = _observer;
final result = widget.builder(controller);
getObs = observer;
return result;
}
@override
Widget build(BuildContext context) => notifyChilds;
}
... ...
... ... @@ -341,6 +341,11 @@ class ListX<E> extends Iterable<E> implements RxInterface<E> {
subject.add(null);
}
void sort([int compare(E a, E b)]) {
_list.sort();
subject.add(null);
}
close() {
_subscriptions.forEach((observable, subscription) {
subscription.cancel();
... ...
... ... @@ -53,5 +53,5 @@ abstract class DisposableInterface {
/// Called before the onDelete method. onClose is used to close events
/// before the controller is destroyed, such as closing streams, for example.
void onClose() async {}
onClose() async {}
}
... ...
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:get/src/get_instance.dart';
import 'package:get/src/root/smart_management.dart';
import 'package:get/src/rx/rx_interface.dart';
import '../get_main.dart';
class GetController extends DisposableInterface {
List<RealState> _allStates = [];
List<Updater> _updaters = [];
/// Update GetBuilder with update();
void update([List<String> ids, bool condition = true]) {
if (!condition) return;
(ids == null)
? _updaters.forEach((rs) {
rs.updater(() {});
})
: _updaters
.where((element) => ids.contains(element.id))
.forEach((rs) => rs.updater(() {}));
}
@override
void onInit() async {}
@override
void onReady() async {}
@override
void onClose() async {}
/// Update GetBuilder with update();
void update([List<String> ids, bool condition = true]) {
if (!condition) return;
if (ids == null) {
_allStates.forEach((rs) {
rs.updater(() {});
});
} else {
ids.forEach(
(s) {
_allStates.forEach((rs) {
if (rs.id == s) rs.updater(() {});
});
},
);
}
}
}
class GetBuilder<T extends GetController> extends StatefulWidget {
... ... @@ -41,6 +30,7 @@ class GetBuilder<T extends GetController> extends StatefulWidget {
final Widget Function(T) builder;
final bool global;
final String id;
final String tag;
final bool autoRemove;
final bool assignId;
final void Function(State state) initState, dispose, didChangeDependencies;
... ... @@ -54,6 +44,7 @@ class GetBuilder<T extends GetController> extends StatefulWidget {
this.autoRemove = true,
this.assignId = false,
this.initState,
this.tag,
this.dispose,
this.id,
this.didChangeDependencies,
... ... @@ -66,44 +57,44 @@ class GetBuilder<T extends GetController> extends StatefulWidget {
class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> {
T controller;
RealState real;
Updater real;
bool isCreator = false;
@override
void initState() {
super.initState();
if (widget.global) {
bool isPrepared = Get.isPrepared<T>();
bool isRegistred = Get.isRegistred<T>();
bool isPrepared = GetInstance().isPrepared<T>(tag: widget.tag);
bool isRegistred = GetInstance().isRegistred<T>(tag: widget.tag);
if (isPrepared) {
if (Get().smartManagement != SmartManagement.keepFactory) {
if (GetConfig.smartManagement != SmartManagement.keepFactory) {
isCreator = true;
}
controller = Get.find<T>();
real = RealState(updater: setState, id: widget.id);
controller._allStates.add(real);
controller = GetInstance().find<T>(tag: widget.tag);
real = Updater(updater: setState, id: widget.id);
controller._updaters.add(real);
} else if (isRegistred) {
controller = Get.find<T>();
controller = GetInstance().find<T>(tag: widget.tag);
isCreator = false;
real = RealState(updater: setState, id: widget.id);
controller._allStates.add(real);
real = Updater(updater: setState, id: widget.id);
controller._updaters.add(real);
} else {
controller = widget.init;
isCreator = true;
real = RealState(updater: setState, id: widget.id);
controller._allStates.add(real);
Get.put<T>(controller);
real = Updater(updater: setState, id: widget.id);
controller._updaters.add(real);
GetInstance().put<T>(controller, tag: widget.tag);
}
} else {
controller = widget.init;
isCreator = true;
real = RealState(updater: setState, id: widget.id);
controller._allStates.add(real);
real = Updater(updater: setState, id: widget.id);
controller._updaters.add(real);
controller?.onStart();
}
if (widget.initState != null) widget.initState(this);
if (isCreator && Get().smartManagement == SmartManagement.onlyBuilder) {
if (isCreator && GetConfig.smartManagement == SmartManagement.onlyBuilder) {
controller?.onStart();
}
}
... ... @@ -113,12 +104,12 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> {
super.dispose();
if (widget.dispose != null) widget.dispose(this);
if (isCreator || widget.assignId) {
if (widget.autoRemove && Get.isRegistred<T>()) {
controller._allStates.remove(real);
Get.delete<T>();
if (widget.autoRemove && GetInstance().isRegistred<T>(tag: widget.tag)) {
controller._updaters.remove(real);
GetInstance().delete<T>(tag: widget.tag);
}
} else {
controller._allStates.remove(real);
controller._updaters.remove(real);
}
}
... ... @@ -141,10 +132,8 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> {
}
}
typedef ShouldRebuild<T> = bool Function(T previous, T next);
class RealState {
class Updater {
final StateSetter updater;
final String id;
const RealState({this.updater, this.id});
const Updater({this.updater, this.id});
}
... ...
typedef FcBuilderFunc<S> = S Function();
typedef FcBuilderFuncAsync<S> = Future<S> Function();
class FcBuilder<S> {
bool isSingleton;
FcBuilderFunc builderFunc;
S dependency;
bool permanent = false;
FcBuilder(this.isSingleton, this.builderFunc, this.permanent);
S getSependency() {
if (isSingleton) {
if (dependency == null) {
dependency = builderFunc() as S;
}
return dependency;
} else {
return builderFunc() as S;
}
}
}
... ...
name: get
description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
version: 2.12.6
version: 2.13.1
homepage: https://github.com/jonataslaw/get
environment:
... ...