Jonatas

update to 3.17.0

## [3.17.0]
- Added GetCupertinoApp
- Added initial suport to navigator 2.0
## [3.16.2]
- Clean RxList, RxMap and RxSet implementation
- Now when declaring an `RxList()`, it will be started empty. If you want to start a null RxList, you must use `RxList(null)`.
... ... @@ -12,13 +16,113 @@ Improved GetStream to receive the same parameters as the StreamController, such
- Added error message callback for StateMixin (@eduardoflorence)
- Fix incorrect Get.reference when pop route (@4mb1t)
- Added Uppercase/Capital letter on GetUtils (@AleFachini)
- Redraw the Streams api to use GetStream instead of StreamControllers. Why this change? GetStream is as light as a ValueNotifier, has very low latency and low consumption of RAM and CPU. The performance difference between Standard Stream and GetStream can exceeds 9000% ([run benchmark by yourself](https://github.com/jonataslaw/getx/blob/master/test/benchmarks/benckmark_test.dart)), making Get unique when it comes to low latency and resource savings. We did this because GetServer needed a low latency solution to optimize the rate of requests, and because today's smartphones are being equipped with increasingly higher refresh rates. There are cell phones today that start at a rate of 120Hz, and the low latency ensures that no frames are lost, ensuring better fluidity. GetStream was then created, released in the previous version, and improved in that version. In the previous version, only a small part of GetX used this low-latency API so that it was possible to verify solidly if the api was mature enough to equip state management, which is the most used feature of this library. After two weeks of unremitting tests, we realized that in addition to being fast, the new api is reliable, and will even equip the Stable version of GetServer, which due to the low latency will have performance of low level languages ​​close to C, C ++, Rust and GO.
- Redraw the Streams api to use GetStream instead of StreamControllers. Why this change?
Dart provides a Streams API that is really rich. However, asynchronous streams add extra latency to ensure that events are delivered in the exact order.
It is not yet known whether this latency has any performance impact in mobile applications, and probably not, however, as GetX is also a server-side framework, we need to have the lowest latency at all, since our base is shared.
Dart also has a Synchronous Streams api that has very low latency, however, it is not suitable for use in state management for two reasons:
1- Synchronous Streams can only have one listen (see the issue opened by Hixie on dart lang for reference: https://github.com/dart-lang/sdk/issues/22240).
This means that we cannot use this api for more than one listener, which is the basis of global state management, where we aim to change the state of more than one location. You can test this with this simple snippet:
```dart
void main() {
var controller = StreamController(sync: true);
var stream = controller.stream;
stream.listen((data) {
print('$data');
if (data == 'test4') controller.add('test5');
});
print('test1');
controller.add('test2');
stream.listen((event) {}); // second listen throws a exception
print('test3');
controller.add('test4');
print('test6');
controller.add('test7');
print("test8");
}
```
2- Even with a single listener, the dart's Synchronous Streams api cannot deliver events in the exact order. We plan to work on a PR in the future at dart-lang to address this. So if we remove the line above that causes the exception, we will have the following output in the log:
```dart
void main() {
var controller = StreamController(sync: true);
var stream = controller.stream;
stream.listen((data) {
print('$data');
if (data == 'test4') controller.add('test5');
});
print('test1');
controller.add('test2');
// stream.listen((event) {}); // second listen throws a exception
print('test3');
controller.add('test4');
print('test6');
controller.add('test7');
print("test8");
}
///////////////////// log:
test1
test2
test3
test4
test6
test8
test5
```
As we can see, test 4 skips to test 6, which skips to test 8, which skips to test 5. Note that test 7 didn't even appear in the log.
However, if we work with GetStream, everything works as expected:
```dart
void main() {
var controller = GetStream();
var stream = controller.stream;
stream.listen((data) {
print('$data');
if (data == 'test4') controller.add('test5');
});
print('test1');
controller.add('test2');
// stream.listen((event) {}); // second listen throws a exception
print('test3');
controller.add('test4');
print('test6');
controller.add('test7');
print("test8");
}
///////////////////// log:
test1
test2
test3
test4
test5
test6
test7
test8
```
The dart documentation is clear that this api should be used with caution, and in view of these tests, we were sure that it is not stable enough to be used as the core of our state management, nor of the websockets notifications and get_server requests.
Clarification about the controversy over benchmarks:
In a version prior to changeLog, we talked about the 9000% difference in performance between Streams, and GetStreams that ended up causing a lot of controversy in the community.
Initially, we would like to clarify that this does not mean that you will have mobile applications 9000% faster. Only that one of our main resources, showed itself with a high rate of requests, 9000% faster than using traditional streams. In a real world scenario, you will hardly have so many simultaneous requests.
Skia renders frames on new devices at up to 120fps. This means that if you have a 10 second animation, you will have 1200 reconstructions. Unless you are working with animations, or something that requires rendering at the skia boundary, you won't need that much power. So this does not mean that we are revolutionizing the mobile world, only that we have created an alternative to Stream Sincronas, which works as expected, and which has satisfactory performance for low latency resources. The benchmarks are real, but that does not mean that you will have mobile applications 9000% faster, but that you have a new feature that performs at this level to use.
For reference only, the benchmark can be found ([HERE](https://github.com/jonataslaw/getx/blob/master/test/benchmarks/benckmark_test.dart))
In short: asynchronous streams from dart work perfectly, but add a latency that we want to remove on Get_server.
Synchronous dart streams have unexpected behaviors, cannot have more than 1 listener and do not deliver events in the correct order, which completely prevents their use in mobile state managements, since you run the risk of displaying data on the wrong screen, since the last event will not always be the last event entered by the sink.
The 9000% figures are real, however, they refer to the gross performance between Streams and GetStreams. This does not mean that this number will impact your applications, because you are unlikely to use all of that power.
## [3.15.0] - Big update
- **Improve Performance**: We made modifications to make GetBuilder even faster. We have improved the structure behind it so that listeners are notified faster. Perhaps in version 4.0 everything will be based on this new structure, but maintaining the power and compatibility with streams. If you want to know how much Getx is faster than pure streams or ChangeNotifier (even after the last update using LinkedList), you can create run the repository tests at: (https://github.com/jonataslaw/getx/blob/master/test/benchmarks/benckmark_test.dart)
- **Added StateMixin**
StateMixin allows you to change the state of the controller, and display a loading, an error message, or a widget you want with 0 boilerplate. This makes things like API / Rest communication or websocket absurdly simple, and it's a real revolution in how state management has behaved so far.
You no longer need to have a ternary in your code, and you don't need a widget like FutureBuilder, StreamBuilder or even Obx / GetBuilder to encompass your Visibility. This will change with the way you manage the state of your controllers, decrease your boilerplate absurdly, and give you more security in your code.
StateMixin allows you to change the state of the controller, and display a loading, an error message, or a widget you want with 0 boilerplate. This makes things like API/Rest communication or websocket absurdly simple, and it's a real revolution in how state management has behaved so far.
You no longer need to have a ternary in your code, and you don't need a widget like FutureBuilder, StreamBuilder or even Obx/GetBuilder to encompass your Visibility. This will change with the way you manage the state of your controllers, decrease your boilerplate absurdly, and give you more security in your code.
- **Added GetNotifier**
GetNotifier is a super and powerful ValueNotifier, which in addition to having the life cycle of the controllers, is extremely fast, and can manage a single state, as a simplified immutable state management solution.
In theory, the only difference between it and GetxController is the possibility of setting an initial value in the constructor's super (exactly as ValueNotifier does). If the initial value is null, use GetxController. If you need a starting value, GetNotifier can be more useful and have less boilerplate, but both serve the same purpose: to decouple your visualization layer from your presentation logic.
... ...
... ... @@ -3,6 +3,7 @@
_Languages: English (this file), [Chinese](README.zh-cn.md), [Brazilian Portuguese](README.pt-br.md), [Spanish](README-es.md), [Russian](README.ru.md), [Polish](README.pl.md)._
[![pub package](https://img.shields.io/pub/v/get.svg?label=get&color=blue)](https://pub.dev/packages/get)
[![likes](https://badges.bar/get/likes)](https://pub.dev/packages/get/score)
![building](https://github.com/jonataslaw/get/workflows/build/badge.svg)
[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart)
[![Discord Shield](https://img.shields.io/discord/722900883784073290.svg?logo=discord)](https://discord.com/invite/9Hpt99N)
... ... @@ -56,7 +57,7 @@ _Languages: English (this file), [Chinese](README.zh-cn.md), [Brazilian Portugue
- GetX has 3 basic principles, this means that this is the priority for all resources in the library: **PRODUCTIVITY, PERFORMANCE AND ORGANIZATION.**
- **PERFORMANCE:** GetX is focused on performance and minimum consumption of resources. GetX does not use Streams or ChangeNotifier like other state managers. Why? In addition to building applications for android, iOS, web, linux, macos and linux, with GetX you can build server applications with the same syntax as Flutter/GetX. In order to improve response time and reduce RAM consumption, we created GetValue and GetStream, which are low latency solutions that deliver a lot of performance, at a low operating cost. We use this base to build all of our resources, including state management. Here ([benchmarks](https://github.com/jonataslaw/getx/blob/master/test/benchmarks/benckmark_test.dart)) there is a test that aims to measure the latency time between ChangeNotifier/GetValue and Streams/GetStreams, specifically measuring the time each of these takes to make 30 to 30,000 status updates. By using simple VoidCallbacks instead of buffering for Streams, RAM consumption is also low. In addition, an application using GetX for state management is also generally smaller than using other approaches. You can test this for yourself using this repository ([state manager approachs](https://github.com/jonataslaw/flutter_state_managers)) that has a simple application with the main state managers of Flutter, which had the collaboration of the creators of each lib, however the difference is small (0.1mb), and you shouldn't choose to use GetX just for that, but mainly because of the two other principles:
- **PERFORMANCE:** GetX is focused on performance and minimum consumption of resources. GetX does not use Streams or ChangeNotifier.
- **PRODUCTIVITY:** GetX uses an easy and pleasant syntax. No matter what you want to do, there is always an easier way with Getx. It will save hours of development, and will extract the maximum performance that your application can deliver.
Generally, the developer should be concerned with removing controllers from memory. With GetX this is not necessary, because resources are removed from memory when they are not used by default. If you want to keep it in memory, you must explicitly declare "permanent: true" in your dependency. That way, in addition to saving time, you are less at risk of having unnecessary dependencies on memory. Dependency loading is also lazy by default.
... ... @@ -66,8 +67,7 @@ _Languages: English (this file), [Chinese](README.zh-cn.md), [Brazilian Portugue
BLoC was a starting point for organizing code in Flutter, it separates business logic from visualization. Getx is a natural evolution of this, not only separating the business logic, but the presentation logic. Bonus injection of dependencies and routes are also decoupled, and the data layer is out of it all. You know where everything is, and all of this in an easier way than building a hello world.
GetX is the easiest, practical and scalable way to build high-performance applications with the Flutter SDK, with a large ecosystem around it that works perfectly together, being easy for beginners, and accurate for experts. It is secure, stable, up-to-date, and offers a huge range of APIs build-in that are not present on default Flutter SDK.
- GetX is not a bloated. It has a multitude of features that allow you to start programming without worrying about anything, but each of these features are in separate containers, and are only started after use. If you only use State Management, only State Management will be compiled. If you only use routes, nothing from the state management will be compiled. You can compile the benchmark repository, and you will see that using only Get state management, the application compiled with Get has become smaller than all other applications that have only the state management of other packages, because nothing that is not used will be compiled into your code, and each GetX solution was designed to be extra lightweight. The merit here also comes from Flutter's tree shaking which is incredible, and manages to eliminate unused resources like no other framework does.
In case you need it, GetX also has separate packages for each resource, but this is probably not necessary, as GetX alone separates the packages in the single library.
- GetX is not a bloated. It has a multitude of features that allow you to start programming without worrying about anything, but each of these features are in separate containers, and are only started after use. If you only use State Management, only State Management will be compiled. If you only use routes, nothing from the state management will be compiled.
- Getx has a huge ecosystem, a large community, a large number of collaborators, and will be maintained as long as the Flutter exists. Getx too is capable of running with the same code on Android, iOS, Web, Mac, Linux, Windows, and on your server.
**It is possible to fully reuse your code made on the frontend on your backend with [Get Server](https://github.com/jonataslaw/get_server)**.
... ...
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'routes/app_pages.dart';
... ... @@ -12,6 +14,7 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
StreamController();
return GetMaterialApp(
debugShowCheckedModeBanner: false,
enableLog: true,
... ...
... ... @@ -11,9 +11,7 @@ class GetInstance {
static GetInstance _getInstance;
T call<T>() {
return find<T>();
}
T call<T>() => find<T>();
/// Holds references to every registered Instance when using
/// [Get.put()]
... ...
... ... @@ -2,7 +2,9 @@ library get_navigation;
export 'src/bottomsheet/bottomsheet.dart';
export 'src/extension_navigation.dart';
export 'src/root/root_widget.dart';
export 'src/root/get_cupertino_app.dart';
export 'src/root/get_material_app.dart';
export 'src/root/internacionalization.dart';
export 'src/routes/custom_transition.dart';
export 'src/routes/default_route.dart';
export 'src/routes/get_route.dart';
... ...
... ... @@ -1051,11 +1051,13 @@ Since version 2.8 it is possible to access the properties
///The number of device pixels for each logical pixel.
double get pixelRatio => window.devicePixelRatio;
Size get size => window.physicalSize / pixelRatio;
///The horizontal extent of this size.
double get width => window.physicalSize.width / pixelRatio;
double get width => size.width;
///The vertical extent of this size
double get height => window.physicalSize.height / pixelRatio;
double get height => size.height;
///The distance from the top edge to the first unpadded pixel,
///in physical pixels.
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../../../get_core/get_core.dart';
import '../../../get_instance/get_instance.dart';
import '../../../get_state_manager/get_state_manager.dart';
import '../../../get_utils/get_utils.dart';
import '../../get_navigation.dart';
import 'root_controller.dart';
class GetCupertinoApp extends StatelessWidget {
const GetCupertinoApp({
Key key,
this.theme,
this.navigatorKey,
this.home,
this.routes = const <String, WidgetBuilder>{},
this.initialRoute,
this.onGenerateRoute,
this.onGenerateInitialRoutes,
this.onUnknownRoute,
this.navigatorObservers = const <NavigatorObserver>[],
this.builder,
this.translationsKeys,
this.translations,
this.textDirection,
this.title = '',
this.onGenerateTitle,
this.color,
this.customTransition,
this.onInit,
this.onDispose,
this.locale,
this.fallbackLocale,
this.localizationsDelegates,
this.localeListResolutionCallback,
this.localeResolutionCallback,
this.supportedLocales = const <Locale>[Locale('en', 'US')],
this.showPerformanceOverlay = false,
this.checkerboardRasterCacheImages = false,
this.checkerboardOffscreenLayers = false,
this.showSemanticsDebugger = false,
this.debugShowCheckedModeBanner = true,
this.shortcuts,
this.smartManagement = SmartManagement.full,
this.initialBinding,
this.unknownRoute,
this.routingCallback,
this.defaultTransition,
this.onReady,
this.getPages,
this.opaqueRoute,
this.enableLog,
this.logWriterCallback,
this.popGesture,
this.transitionDuration,
this.defaultGlobalState,
this.highContrastTheme,
this.highContrastDarkTheme,
this.actions,
}) : assert(routes != null),
assert(navigatorObservers != null),
assert(title != null),
assert(showPerformanceOverlay != null),
assert(checkerboardRasterCacheImages != null),
assert(checkerboardOffscreenLayers != null),
assert(showSemanticsDebugger != null),
assert(debugShowCheckedModeBanner != null),
routeInformationProvider = null,
routeInformationParser = null,
routerDelegate = null,
backButtonDispatcher = null,
super(key: key);
final GlobalKey<NavigatorState> navigatorKey;
final Widget home;
final Map<String, WidgetBuilder> routes;
final String initialRoute;
final RouteFactory onGenerateRoute;
final InitialRouteListFactory onGenerateInitialRoutes;
final RouteFactory onUnknownRoute;
final List<NavigatorObserver> navigatorObservers;
final TransitionBuilder builder;
final String title;
final GenerateAppTitle onGenerateTitle;
final CustomTransition customTransition;
final Color color;
final Map<String, Map<String, String>> translationsKeys;
final Translations translations;
final TextDirection textDirection;
final Locale locale;
final Locale fallbackLocale;
final Iterable<LocalizationsDelegate<dynamic>> localizationsDelegates;
final LocaleListResolutionCallback localeListResolutionCallback;
final LocaleResolutionCallback localeResolutionCallback;
final Iterable<Locale> supportedLocales;
final bool showPerformanceOverlay;
final bool checkerboardRasterCacheImages;
final bool checkerboardOffscreenLayers;
final bool showSemanticsDebugger;
final bool debugShowCheckedModeBanner;
final Map<LogicalKeySet, Intent> shortcuts;
final ThemeData highContrastTheme;
final ThemeData highContrastDarkTheme;
final Map<Type, Action<Intent>> actions;
final Function(Routing) routingCallback;
final Transition defaultTransition;
final bool opaqueRoute;
final VoidCallback onInit;
final VoidCallback onReady;
final VoidCallback onDispose;
final bool enableLog;
final LogWriterCallback logWriterCallback;
final bool popGesture;
final SmartManagement smartManagement;
final Bindings initialBinding;
final Duration transitionDuration;
final bool defaultGlobalState;
final List<GetPage> getPages;
final GetPage unknownRoute;
final RouteInformationProvider routeInformationProvider;
final RouteInformationParser<Object> routeInformationParser;
final RouterDelegate<Object> routerDelegate;
final BackButtonDispatcher backButtonDispatcher;
final CupertinoThemeData theme;
const GetCupertinoApp.router({
Key key,
this.theme,
this.routeInformationProvider,
@required this.routeInformationParser,
@required this.routerDelegate,
this.backButtonDispatcher,
this.builder,
this.title = '',
this.onGenerateTitle,
this.color,
this.highContrastTheme,
this.highContrastDarkTheme,
this.locale,
this.localizationsDelegates,
this.localeListResolutionCallback,
this.localeResolutionCallback,
this.supportedLocales = const <Locale>[Locale('en', 'US')],
this.showPerformanceOverlay = false,
this.checkerboardRasterCacheImages = false,
this.checkerboardOffscreenLayers = false,
this.showSemanticsDebugger = false,
this.debugShowCheckedModeBanner = true,
this.shortcuts,
this.actions,
this.customTransition,
this.translationsKeys,
this.translations,
this.textDirection,
this.fallbackLocale,
this.routingCallback,
this.defaultTransition,
this.opaqueRoute,
this.onInit,
this.onReady,
this.onDispose,
this.enableLog,
this.logWriterCallback,
this.popGesture,
this.smartManagement = SmartManagement.full,
this.initialBinding,
this.transitionDuration,
this.defaultGlobalState,
this.getPages,
this.unknownRoute,
}) : assert(routeInformationParser != null),
assert(routerDelegate != null),
assert(title != null),
assert(showPerformanceOverlay != null),
assert(checkerboardRasterCacheImages != null),
assert(checkerboardOffscreenLayers != null),
assert(showSemanticsDebugger != null),
assert(debugShowCheckedModeBanner != null),
navigatorObservers = null,
navigatorKey = null,
onGenerateRoute = null,
home = null,
onGenerateInitialRoutes = null,
onUnknownRoute = null,
routes = null,
initialRoute = null,
super(key: key);
Route<dynamic> generator(RouteSettings settings) {
final match = Get.routeTree.matchRoute(settings.name);
Get.parameters = match?.parameters;
if (match?.route == null) {
return GetPageRoute(
page: unknownRoute.page,
parameter: unknownRoute.parameter,
settings:
RouteSettings(name: settings.name, arguments: settings.arguments),
curve: unknownRoute.curve,
opaque: unknownRoute.opaque,
customTransition: unknownRoute.customTransition,
binding: unknownRoute.binding,
bindings: unknownRoute.bindings,
transitionDuration:
(unknownRoute.transitionDuration ?? Get.defaultTransitionDuration),
transition: unknownRoute.transition,
popGesture: unknownRoute.popGesture,
fullscreenDialog: unknownRoute.fullscreenDialog,
);
}
return GetPageRoute(
page: match.route.page,
parameter: match.route.parameter,
settings:
RouteSettings(name: settings.name, arguments: settings.arguments),
curve: match.route.curve,
opaque: match.route.opaque,
customTransition: match.route.customTransition,
binding: match.route.binding,
bindings: match.route.bindings,
transitionDuration:
(match.route.transitionDuration ?? Get.defaultTransitionDuration),
transition: match.route.transition,
popGesture: match.route.popGesture,
fullscreenDialog: match.route.fullscreenDialog,
);
}
List<Route<dynamic>> initialRoutesGenerate(String name) {
final match = Get.routeTree.matchRoute(name);
Get.parameters = match?.parameters;
//Route can be nullable, just pass the unknown route
if (match?.route == null) {
return [
GetPageRoute(
page: unknownRoute.page,
parameter: unknownRoute.parameter,
settings: RouteSettings(name: name, arguments: null),
curve: unknownRoute.curve,
opaque: unknownRoute.opaque,
customTransition: unknownRoute.customTransition,
binding: unknownRoute.binding,
bindings: unknownRoute.bindings,
transitionDuration: (unknownRoute.transitionDuration ??
Get.defaultTransitionDuration),
transition: unknownRoute.transition,
popGesture: unknownRoute.popGesture,
fullscreenDialog: unknownRoute.fullscreenDialog,
)
];
}
return [
GetPageRoute(
page: match.route.page,
parameter: match.route.parameter,
settings: RouteSettings(name: name, arguments: null),
curve: match.route.curve,
opaque: match.route.opaque,
binding: match.route.binding,
bindings: match.route.bindings,
transitionDuration:
(match.route.transitionDuration ?? Get.defaultTransitionDuration),
transition: match.route.transition,
popGesture: match.route.popGesture,
fullscreenDialog: match.route.fullscreenDialog,
)
];
}
@override
Widget build(BuildContext context) {
return GetBuilder<GetMaterialController>(
init: Get.rootController,
dispose: (d) {
onDispose?.call();
},
initState: (i) {
Get.engine.addPostFrameCallback((timeStamp) {
onReady?.call();
});
if (locale != null) Get.locale = locale;
if (fallbackLocale != null) Get.fallbackLocale = fallbackLocale;
if (translations != null) {
Get.addTranslations(translations.keys);
} else if (translationsKeys != null) {
Get.addTranslations(translationsKeys);
}
Get.customTransition = customTransition;
initialBinding?.dependencies();
Get.addPages(getPages);
Get.smartManagement = smartManagement;
onInit?.call();
Get.config(
enableLog: enableLog ?? Get.isLogEnable,
logWriterCallback: logWriterCallback,
defaultTransition: defaultTransition ?? Get.defaultTransition,
defaultOpaqueRoute: opaqueRoute ?? Get.isOpaqueRouteDefault,
defaultPopGesture: popGesture ?? Get.isPopGestureEnable,
defaultDurationTransition:
transitionDuration ?? Get.defaultTransitionDuration,
);
},
builder: (_) {
return CupertinoApp(
key: _.unikey,
theme: theme,
navigatorKey:
(navigatorKey == null ? Get.key : Get.addKey(navigatorKey)),
home: home,
routes: routes ?? const <String, WidgetBuilder>{},
initialRoute: initialRoute,
onGenerateRoute: (getPages != null ? generator : onGenerateRoute),
onGenerateInitialRoutes: (getPages == null || home != null)
? onGenerateInitialRoutes
: initialRoutesGenerate,
onUnknownRoute: onUnknownRoute,
navigatorObservers: (navigatorObservers == null
? <NavigatorObserver>[GetObserver(routingCallback, Get.routing)]
: <NavigatorObserver>[GetObserver(routingCallback, Get.routing)]
..addAll(navigatorObservers)),
builder: (context, child) {
return Directionality(
textDirection: textDirection ??
(rtlLanguages.contains(Get.locale?.languageCode)
? TextDirection.rtl
: TextDirection.ltr),
child: builder == null ? child : builder(context, child),
);
},
title: title ?? '',
onGenerateTitle: onGenerateTitle,
color: color,
locale: Get.locale ?? locale,
localizationsDelegates: localizationsDelegates,
localeListResolutionCallback: localeListResolutionCallback,
localeResolutionCallback: localeResolutionCallback,
supportedLocales:
supportedLocales ?? const <Locale>[Locale('en', 'US')],
showPerformanceOverlay: showPerformanceOverlay ?? false,
checkerboardRasterCacheImages:
checkerboardRasterCacheImages ?? false,
checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false,
showSemanticsDebugger: showSemanticsDebugger ?? false,
debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true,
shortcuts: shortcuts,
// actions: actions,
);
});
}
}
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../../../get_core/get_core.dart';
... ... @@ -19,15 +20,10 @@ class GetMaterialApp extends StatelessWidget {
this.onUnknownRoute,
this.navigatorObservers = const <NavigatorObserver>[],
this.builder,
this.translationsKeys,
this.translations,
this.textDirection,
this.title = '',
this.onGenerateTitle,
this.color,
this.customTransition,
this.onInit,
this.onDispose,
this.theme,
this.darkTheme,
this.themeMode = ThemeMode.system,
... ... @@ -44,12 +40,14 @@ class GetMaterialApp extends StatelessWidget {
this.showSemanticsDebugger = false,
this.debugShowCheckedModeBanner = true,
this.shortcuts,
this.smartManagement = SmartManagement.full,
this.initialBinding,
this.unknownRoute,
this.customTransition,
this.translationsKeys,
this.translations,
this.onInit,
this.onReady,
this.onDispose,
this.routingCallback,
this.defaultTransition,
// this.actions,
this.getPages,
this.opaqueRoute,
this.enableLog,
... ... @@ -57,6 +55,12 @@ class GetMaterialApp extends StatelessWidget {
this.popGesture,
this.transitionDuration,
this.defaultGlobalState,
this.smartManagement = SmartManagement.full,
this.initialBinding,
this.unknownRoute,
this.highContrastTheme,
this.highContrastDarkTheme,
this.actions,
}) : assert(routes != null),
assert(navigatorObservers != null),
assert(title != null),
... ... @@ -66,6 +70,10 @@ class GetMaterialApp extends StatelessWidget {
assert(checkerboardOffscreenLayers != null),
assert(showSemanticsDebugger != null),
assert(debugShowCheckedModeBanner != null),
routeInformationProvider = null,
routeInformationParser = null,
routerDelegate = null,
backButtonDispatcher = null,
super(key: key);
final GlobalKey<NavigatorState> navigatorKey;
... ... @@ -99,13 +107,15 @@ class GetMaterialApp extends StatelessWidget {
final bool showSemanticsDebugger;
final bool debugShowCheckedModeBanner;
final Map<LogicalKeySet, Intent> shortcuts;
// final Map<LocalKey, ActionFactory> actions;
final ThemeData highContrastTheme;
final ThemeData highContrastDarkTheme;
final Map<Type, Action<Intent>> actions;
final bool debugShowMaterialGrid;
final Function(Routing) routingCallback;
final Transition defaultTransition;
final bool opaqueRoute;
final VoidCallback onInit;
final VoidCallback onReady;
final VoidCallback onDispose;
final bool enableLog;
final LogWriterCallback logWriterCallback;
... ... @@ -116,6 +126,77 @@ class GetMaterialApp extends StatelessWidget {
final bool defaultGlobalState;
final List<GetPage> getPages;
final GetPage unknownRoute;
final RouteInformationProvider routeInformationProvider;
final RouteInformationParser<Object> routeInformationParser;
final RouterDelegate<Object> routerDelegate;
final BackButtonDispatcher backButtonDispatcher;
const GetMaterialApp.router({
Key key,
this.routeInformationProvider,
@required this.routeInformationParser,
@required this.routerDelegate,
this.backButtonDispatcher,
this.builder,
this.title = '',
this.onGenerateTitle,
this.color,
this.theme,
this.darkTheme,
this.highContrastTheme,
this.highContrastDarkTheme,
this.themeMode = ThemeMode.system,
this.locale,
this.localizationsDelegates,
this.localeListResolutionCallback,
this.localeResolutionCallback,
this.supportedLocales = const <Locale>[Locale('en', 'US')],
this.debugShowMaterialGrid = false,
this.showPerformanceOverlay = false,
this.checkerboardRasterCacheImages = false,
this.checkerboardOffscreenLayers = false,
this.showSemanticsDebugger = false,
this.debugShowCheckedModeBanner = true,
this.shortcuts,
this.actions,
this.customTransition,
this.translationsKeys,
this.translations,
this.textDirection,
this.fallbackLocale,
this.routingCallback,
this.defaultTransition,
this.opaqueRoute,
this.onInit,
this.onReady,
this.onDispose,
this.enableLog,
this.logWriterCallback,
this.popGesture,
this.smartManagement = SmartManagement.full,
this.initialBinding,
this.transitionDuration,
this.defaultGlobalState,
this.getPages,
this.unknownRoute,
}) : assert(routeInformationParser != null),
assert(routerDelegate != null),
assert(title != null),
assert(debugShowMaterialGrid != null),
assert(showPerformanceOverlay != null),
assert(checkerboardRasterCacheImages != null),
assert(checkerboardOffscreenLayers != null),
assert(showSemanticsDebugger != null),
assert(debugShowCheckedModeBanner != null),
navigatorObservers = null,
navigatorKey = null,
onGenerateRoute = null,
home = null,
onGenerateInitialRoutes = null,
onUnknownRoute = null,
routes = null,
initialRoute = null,
super(key: key);
Route<dynamic> generator(RouteSettings settings) {
final match = Get.routeTree.matchRoute(settings.name);
... ... @@ -209,6 +290,9 @@ class GetMaterialApp extends StatelessWidget {
onDispose?.call();
},
initState: (i) {
Get.engine.addPostFrameCallback((timeStamp) {
onReady?.call();
});
if (locale != null) Get.locale = locale;
if (fallbackLocale != null) Get.fallbackLocale = fallbackLocale;
... ... @@ -287,15 +371,3 @@ class GetMaterialApp extends StatelessWidget {
});
}
}
const List<String> rtlLanguages = <String>[
'ar', // Arabic
'fa', // Farsi
'he', // Hebrew
'ps', // Pashto
'ur',
];
abstract class Translations {
Map<String, Map<String, String>> get keys;
}
... ...
const List<String> rtlLanguages = <String>[
'ar', // Arabic
'fa', // Farsi
'he', // Hebrew
'ps', // Pashto
'ur',
];
abstract class Translations {
Map<String, Map<String, String>> get keys;
}
... ...
import 'package:flutter/widgets.dart';
import '../routes/get_route.dart';
class ParseRouteTree {
... ...
name: get
description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with GetX.
version: 3.16.2
version: 3.17.0
homepage: https://github.com/jonataslaw/getx
environment:
... ...