Showing
10 changed files
with
232 additions
and
144 deletions
1 | +## [2.5.2] | ||
2 | +- Fix: key not found when Get.key is used with no MaterialApp | ||
3 | + | ||
4 | +## [2.5.1] | ||
5 | +- Improve - GetBuilder uses 18% less ram on more of 20 controllers. | ||
6 | + | ||
1 | ## [2.5.0] | 7 | ## [2.5.0] |
2 | - Added List.obs | 8 | - Added List.obs |
3 | - Now you can transform any class on obs | 9 | - Now you can transform any class on obs |
@@ -23,6 +23,23 @@ Flutter's conventional navigation has a lot of unnecessary boilerplate, requires | @@ -23,6 +23,23 @@ Flutter's conventional navigation has a lot of unnecessary boilerplate, requires | ||
23 | In addition, when a route is pushed, the entire MaterialApp can be rebuilt causing freezes, this does not happen with Get. | 23 | In addition, when a route is pushed, the entire MaterialApp can be rebuilt causing freezes, this does not happen with Get. |
24 | This library that will change the way you work with the Framework and save your life from cliche code, increasing your productivity, and eliminating the rebuild bugs of your application. | 24 | This library that will change the way you work with the Framework and save your life from cliche code, increasing your productivity, and eliminating the rebuild bugs of your application. |
25 | 25 | ||
26 | + | ||
27 | +- **[How to use?](#how-to-use)** | ||
28 | +- **[Navigating without named routes](#Navigating-without-named-routes)** | ||
29 | +- **[SnackBars](#SnackBars)** | ||
30 | +- **[Dialogs](#Dialogs)** | ||
31 | +- **[BottomSheets](#BottomSheets)** | ||
32 | +- **[Simple State Manager](#Simple-State-Manager)** | ||
33 | +- **[Reactive State Manager](#Reactive-State-Manager)** | ||
34 | +- **[Simple Instance Manager](#Simple-Instance-Manager)** | ||
35 | +- **[Navigate with named routes](#Navigate-with-named-routes)** | ||
36 | +- **[Send data to named Routes](#Send-data-to-named-Routes)** | ||
37 | +- **[Dynamic urls links](#Dynamic-urls-links)** | ||
38 | +- **[Middleware](#Middleware)** | ||
39 | +- **[Optional Global Settings](#Optional-Global-Settings)** | ||
40 | +- **[Other Advanced APIs and Manual configurations](#Other-Advanced-APIs-and-Manual-configurations)** | ||
41 | +- **[Nested Navigators](#Nested-Navigators)** | ||
42 | + | ||
26 | ## How to use? | 43 | ## How to use? |
27 | 44 | ||
28 | <!-- - Flutter Master/Dev/Beta: version 2.0.x-dev | 45 | <!-- - Flutter Master/Dev/Beta: version 2.0.x-dev |
@@ -39,7 +56,7 @@ GetMaterialApp( // Before: MaterialApp( | @@ -39,7 +56,7 @@ GetMaterialApp( // Before: MaterialApp( | ||
39 | home: MyHome(), | 56 | home: MyHome(), |
40 | ) | 57 | ) |
41 | ``` | 58 | ``` |
42 | -### Navigating without named routes | 59 | +## Navigating without named routes |
43 | To navigate to a new screen: | 60 | To navigate to a new screen: |
44 | 61 | ||
45 | ```dart | 62 | ```dart |
@@ -153,6 +170,7 @@ With Get, all you have to do is call your Get.snackbar from anywhere in your cod | @@ -153,6 +170,7 @@ With Get, all you have to do is call your Get.snackbar from anywhere in your cod | ||
153 | // SnackPosition snackPosition, | 170 | // SnackPosition snackPosition, |
154 | // Widget titleText, | 171 | // Widget titleText, |
155 | // Widget messageText, | 172 | // Widget messageText, |
173 | + // bool instantInit, | ||
156 | // Widget icon, | 174 | // Widget icon, |
157 | // bool shouldIconPulse, | 175 | // bool shouldIconPulse, |
158 | // double maxWidth, | 176 | // double maxWidth, |
@@ -242,7 +260,7 @@ What performance improvements does Get bring? | @@ -242,7 +260,7 @@ What performance improvements does Get bring? | ||
242 | 260 | ||
243 | 1- Update only the required widget. | 261 | 1- Update only the required widget. |
244 | 262 | ||
245 | -2- Does not use changeNotifier, it is the state manager that uses less memory (close to 0mb). | 263 | +2- Does not use changeNotifier, it is the state manager that uses less memory (close to 0mb for until). |
246 | 264 | ||
247 | 3- Forget StatefulWidget! With Get you will never need it again (if you need to use it, you are using Get incorrectly). With the other state managers, you will probably have to use a StatefulWidget to get the instance of your Provider, BLoC, MobX Controller, etc. But have you ever stopped to think that your appBar, your scaffold, and most of the widgets that are in your class are stateless? So why save the state of an entire class, if you can only save the state of the Widget that is stateful? Get solves that, too. Create a Stateless class, make everything stateless. If you need to update a single component, wrap it with GetBuilder, and its state will be maintained. | 265 | 3- Forget StatefulWidget! With Get you will never need it again (if you need to use it, you are using Get incorrectly). With the other state managers, you will probably have to use a StatefulWidget to get the instance of your Provider, BLoC, MobX Controller, etc. But have you ever stopped to think that your appBar, your scaffold, and most of the widgets that are in your class are stateless? So why save the state of an entire class, if you can only save the state of the Widget that is stateful? Get solves that, too. Create a Stateless class, make everything stateless. If you need to update a single component, wrap it with GetBuilder, and its state will be maintained. |
248 | 266 | ||
@@ -329,7 +347,7 @@ FloatingActionButton( | @@ -329,7 +347,7 @@ FloatingActionButton( | ||
329 | ``` | 347 | ``` |
330 | When you press FloatingActionButton, all widgets that are listening to the 'counter' variable will be updated automatically. | 348 | When you press FloatingActionButton, all widgets that are listening to the 'counter' variable will be updated automatically. |
331 | 349 | ||
332 | -##### No StatefulWidget: | 350 | +#### No StatefulWidget: |
333 | Using StatefulWidgets means storing the state of entire screens unnecessarily. With Get the use of StatefulWidget is optional. Avoid them and save your users' RAM. | 351 | Using StatefulWidgets means storing the state of entire screens unnecessarily. With Get the use of StatefulWidget is optional. Avoid them and save your users' RAM. |
334 | 352 | ||
335 | If you need to call initState() or dispose() method, you can call them directly from GetBuilder(); | 353 | If you need to call initState() or dispose() method, you can call them directly from GetBuilder(); |
@@ -434,8 +452,6 @@ You can also impose conditions for the update: | @@ -434,8 +452,6 @@ You can also impose conditions for the update: | ||
434 | ``` | 452 | ``` |
435 | update(this,['text'], counter < 10); | 453 | update(this,['text'], counter < 10); |
436 | 454 | ||
437 | -Why use the update method and why don't we use ChangeNotifier? | ||
438 | - | ||
439 | 455 | ||
440 | ## Reactive State Manager | 456 | ## Reactive State Manager |
441 | 457 | ||
@@ -537,6 +553,7 @@ Camila | @@ -537,6 +553,7 @@ Camila | ||
537 | 23 | 553 | 23 |
538 | 24 | 554 | 24 |
539 | 25 | 555 | 25 |
556 | + | ||
540 | ``` | 557 | ``` |
541 | 558 | ||
542 | ## Simple Instance Manager | 559 | ## Simple Instance Manager |
@@ -805,7 +822,7 @@ Get.config( | @@ -805,7 +822,7 @@ Get.config( | ||
805 | 822 | ||
806 | 823 | ||
807 | ### Other Advanced APIs and Manual configurations | 824 | ### Other Advanced APIs and Manual configurations |
808 | -GetMaterialApp configures everything for you, but if you are using any package like Modular, you may want to configure Get Manually using advanced APIs. | 825 | +GetMaterialApp configures everything for you, but if you want to configure Get Manually using advanced APIs. |
809 | 826 | ||
810 | ```dart | 827 | ```dart |
811 | MaterialApp( | 828 | MaterialApp( |
@@ -863,6 +880,8 @@ Get.contextOverlay // Gives the context of the snackbar/dialog/bottomsheet in th | @@ -863,6 +880,8 @@ Get.contextOverlay // Gives the context of the snackbar/dialog/bottomsheet in th | ||
863 | Get made Flutter's nested navigation even easier. | 880 | Get made Flutter's nested navigation even easier. |
864 | You don't need the context, and you will find your navigation stack by Id. | 881 | You don't need the context, and you will find your navigation stack by Id. |
865 | 882 | ||
883 | +- NOTE: Creating parallel navigation stacks can be dangerous. The ideal is not to use NestedNavigators, or to use sparingly. If your project requires it, go ahead, but keep in mind that keeping multiple navigation stacks in memory may not be a good idea for RAM consumption. | ||
884 | + | ||
866 | See how simple it is: | 885 | See how simple it is: |
867 | ```dart | 886 | ```dart |
868 | Navigator( | 887 | Navigator( |
@@ -42,18 +42,6 @@ class Get { | @@ -42,18 +42,6 @@ class Get { | ||
42 | 42 | ||
43 | GlobalKey<NavigatorState> _key; | 43 | GlobalKey<NavigatorState> _key; |
44 | 44 | ||
45 | - static GlobalKey<NavigatorState> addKey(GlobalKey<NavigatorState> newKey) { | ||
46 | - _get._key = newKey; | ||
47 | - return _get._key; | ||
48 | - } | ||
49 | - | ||
50 | - static GlobalKey<NavigatorState> get key { | ||
51 | - if (_get._key == null) { | ||
52 | - _get._key = GlobalKey<NavigatorState>(); | ||
53 | - } | ||
54 | - return _get._key; | ||
55 | - } | ||
56 | - | ||
57 | /// It replaces Navigator.push, but needs no context, and it doesn't have the Navigator.push | 45 | /// It replaces Navigator.push, but needs no context, and it doesn't have the Navigator.push |
58 | /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior | 46 | /// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior |
59 | /// of rebuilding every app after a route, use opaque = true as the parameter. | 47 | /// of rebuilding every app after a route, use opaque = true as the parameter. |
@@ -268,6 +256,8 @@ class Get { | @@ -268,6 +256,8 @@ class Get { | ||
268 | VoidCallback onConfirm, | 256 | VoidCallback onConfirm, |
269 | VoidCallback onCancel, | 257 | VoidCallback onCancel, |
270 | VoidCallback onCustom, | 258 | VoidCallback onCustom, |
259 | + Color cancelTextColor, | ||
260 | + Color confirmTextColor, | ||
271 | String textConfirm, | 261 | String textConfirm, |
272 | String textCancel, | 262 | String textCancel, |
273 | String textCustom, | 263 | String textCustom, |
@@ -295,7 +285,10 @@ class Get { | @@ -295,7 +285,10 @@ class Get { | ||
295 | Get.back(); | 285 | Get.back(); |
296 | }, | 286 | }, |
297 | padding: EdgeInsets.symmetric(horizontal: 10, vertical: 8), | 287 | padding: EdgeInsets.symmetric(horizontal: 10, vertical: 8), |
298 | - child: Text(textCancel ?? "Cancel"), | 288 | + child: Text( |
289 | + textCancel ?? "Cancel", | ||
290 | + style: TextStyle(color: cancelTextColor ?? theme.accentColor), | ||
291 | + ), | ||
299 | shape: RoundedRectangleBorder( | 292 | shape: RoundedRectangleBorder( |
300 | side: BorderSide( | 293 | side: BorderSide( |
301 | color: buttonColor ?? Get.theme.accentColor, | 294 | color: buttonColor ?? Get.theme.accentColor, |
@@ -314,7 +307,10 @@ class Get { | @@ -314,7 +307,10 @@ class Get { | ||
314 | color: buttonColor ?? Get.theme.accentColor, | 307 | color: buttonColor ?? Get.theme.accentColor, |
315 | shape: RoundedRectangleBorder( | 308 | shape: RoundedRectangleBorder( |
316 | borderRadius: BorderRadius.circular(100)), | 309 | borderRadius: BorderRadius.circular(100)), |
317 | - child: Text(textConfirm ?? "Ok"), | 310 | + child: Text( |
311 | + textConfirm ?? "Ok", | ||
312 | + style: TextStyle(color: confirmTextColor ?? theme.primaryColor), | ||
313 | + ), | ||
318 | onPressed: () { | 314 | onPressed: () { |
319 | onConfirm?.call(); | 315 | onConfirm?.call(); |
320 | })); | 316 | })); |
@@ -607,6 +603,19 @@ class Get { | @@ -607,6 +603,19 @@ class Get { | ||
607 | _get._getController.restartApp(); | 603 | _get._getController.restartApp(); |
608 | } | 604 | } |
609 | 605 | ||
606 | + static GlobalKey<NavigatorState> addKey(GlobalKey<NavigatorState> newKey) { | ||
607 | + Get()._key = newKey; | ||
608 | + return Get()._key; | ||
609 | + } | ||
610 | + | ||
611 | + static GlobalKey<NavigatorState> get key { | ||
612 | + // _get start empty, is mandatory key be static to prevent errors like "key was called null" | ||
613 | + if (Get()._key == null) { | ||
614 | + Get()._key = GlobalKey<NavigatorState>(); | ||
615 | + } | ||
616 | + return Get()._key; | ||
617 | + } | ||
618 | + | ||
610 | Map<int, GlobalKey<NavigatorState>> _keys = {}; | 619 | Map<int, GlobalKey<NavigatorState>> _keys = {}; |
611 | 620 | ||
612 | static GlobalKey<NavigatorState> nestedKey(int key) { | 621 | static GlobalKey<NavigatorState> nestedKey(int key) { |
@@ -678,7 +687,7 @@ class Get { | @@ -678,7 +687,7 @@ class Get { | ||
678 | } | 687 | } |
679 | 688 | ||
680 | /// Find a instance from required class | 689 | /// Find a instance from required class |
681 | - static S find<S>({String name}) { | 690 | + static S find<S>({String name, _FcBuilderFunc<S> instance}) { |
682 | if (Get.isRegistred<S>()) { | 691 | if (Get.isRegistred<S>()) { |
683 | String key = _getKey(S, name); | 692 | String key = _getKey(S, name); |
684 | _FcBuilder builder = Get()._singl[key]; | 693 | _FcBuilder builder = Get()._singl[key]; |
@@ -701,6 +710,30 @@ class Get { | @@ -701,6 +710,30 @@ class Get { | ||
701 | } | 710 | } |
702 | } | 711 | } |
703 | 712 | ||
713 | + static S findInstance<S>(_FcBuilderFunc<S> instance, {String name}) { | ||
714 | + if (Get()._singl.containsKey(_getKey(instance.call().runtimeType, name))) { | ||
715 | + String key = _getKey(instance.call().runtimeType, name); | ||
716 | + _FcBuilder builder = Get()._singl[key]; | ||
717 | + if (builder == null) { | ||
718 | + if (name == null) { | ||
719 | + throw "class ${S.toString()} is not register"; | ||
720 | + } else { | ||
721 | + throw "class ${S.toString()} with name '$name' is not register"; | ||
722 | + } | ||
723 | + } | ||
724 | + return Get()._singl[key].getSependency(); | ||
725 | + } else { | ||
726 | + if (!Get()._factory.containsKey(instance.call().runtimeType)) | ||
727 | + throw " $S not found. You need call Get.put<$S>($S()) before"; | ||
728 | + | ||
729 | + if (isLogEnable) print('[GET] $S instance was created at that time'); | ||
730 | + S _value = | ||
731 | + Get.put<S>(Get()._factory[instance.call().runtimeType].call() as S); | ||
732 | + Get()._factory.remove(instance.call().runtimeType); | ||
733 | + return _value; | ||
734 | + } | ||
735 | + } | ||
736 | + | ||
704 | /// Remove dependency of [S] on dependency abstraction. For concrete class use Get.delete | 737 | /// Remove dependency of [S] on dependency abstraction. For concrete class use Get.delete |
705 | static void remove<S>({String name}) { | 738 | static void remove<S>({String name}) { |
706 | String key = _getKey(S, name); | 739 | String key = _getKey(S, name); |
@@ -753,15 +786,15 @@ class Get { | @@ -753,15 +786,15 @@ class Get { | ||
753 | Map<String, String> _parameters = {}; | 786 | Map<String, String> _parameters = {}; |
754 | 787 | ||
755 | Get.setParameter(Map<String, String> param) { | 788 | Get.setParameter(Map<String, String> param) { |
756 | - _get._parameters = param; | 789 | + _parameters = param; |
757 | } | 790 | } |
758 | 791 | ||
759 | Get.setRouting(Routing rt) { | 792 | Get.setRouting(Routing rt) { |
760 | - _get._routing = rt; | 793 | + _routing = rt; |
761 | } | 794 | } |
762 | 795 | ||
763 | Get.setSettings(RouteSettings settings) { | 796 | Get.setSettings(RouteSettings settings) { |
764 | - _get._settings = settings; | 797 | + _settings = settings; |
765 | } | 798 | } |
766 | 799 | ||
767 | /// give current arguments | 800 | /// give current arguments |
@@ -5,7 +5,6 @@ import 'package:get/src/routes/utils/parse_arguments.dart'; | @@ -5,7 +5,6 @@ import 'package:get/src/routes/utils/parse_arguments.dart'; | ||
5 | import 'root_controller.dart'; | 5 | import 'root_controller.dart'; |
6 | 6 | ||
7 | class GetMaterialApp extends StatelessWidget { | 7 | class GetMaterialApp extends StatelessWidget { |
8 | - | ||
9 | const GetMaterialApp({ | 8 | const GetMaterialApp({ |
10 | Key key, | 9 | Key key, |
11 | this.navigatorKey, | 10 | this.navigatorKey, |
@@ -31,7 +31,7 @@ class _GetXState<T extends RxController> extends State<GetX<T>> { | @@ -31,7 +31,7 @@ class _GetXState<T extends RxController> extends State<GetX<T>> { | ||
31 | T controller; | 31 | T controller; |
32 | 32 | ||
33 | _GetXState() { | 33 | _GetXState() { |
34 | - _observer = Rx(); | 34 | + _observer = ListX(); |
35 | } | 35 | } |
36 | 36 | ||
37 | @override | 37 | @override |
@@ -60,15 +60,23 @@ class _GetXState<T extends RxController> extends State<GetX<T>> { | @@ -60,15 +60,23 @@ class _GetXState<T extends RxController> extends State<GetX<T>> { | ||
60 | 60 | ||
61 | @override | 61 | @override |
62 | void dispose() { | 62 | void dispose() { |
63 | - controller?.close(); | 63 | + if (widget.dispose != null) widget.dispose(this); |
64 | + | ||
65 | + if (widget.init != null) { | ||
66 | + if (widget.autoRemove && Get.isRegistred<T>()) { | ||
67 | + controller.onClose(); | ||
68 | + Get.delete<T>(); | ||
69 | + } | ||
70 | + } | ||
71 | + controller.onClose(); | ||
72 | + _observer.close(); | ||
64 | _listenSubscription?.cancel(); | 73 | _listenSubscription?.cancel(); |
65 | - _observer?.close(); | ||
66 | super.dispose(); | 74 | super.dispose(); |
67 | } | 75 | } |
68 | 76 | ||
69 | @override | 77 | @override |
70 | Widget build(BuildContext context) { | 78 | Widget build(BuildContext context) { |
71 | - _observer.close(); | 79 | + // _observer.close(); |
72 | final observer = Get.obs; | 80 | final observer = Get.obs; |
73 | Get.obs = this._observer; | 81 | Get.obs = this._observer; |
74 | final result = widget.builder(controller); | 82 | final result = widget.builder(controller); |
@@ -145,7 +145,13 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | @@ -145,7 +145,13 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | ||
145 | 145 | ||
146 | Map<Stream<Change<E>>, StreamSubscription> _subscriptions = Map(); | 146 | Map<Stream<Change<E>>, StreamSubscription> _subscriptions = Map(); |
147 | 147 | ||
148 | - final _changeCtl = StreamController<Change<E>>(); | 148 | + // StreamSubscription _changectl = StreamSubscription(); |
149 | + | ||
150 | + StreamController<Change<E>> _changeCtl = | ||
151 | + StreamController<Change<E>>.broadcast(); | ||
152 | + | ||
153 | + @override | ||
154 | + StreamController<Change<E>> subject = StreamController<Change<E>>.broadcast(); | ||
149 | 155 | ||
150 | /// Adds [item] only if [condition] resolves to true. | 156 | /// Adds [item] only if [condition] resolves to true. |
151 | void addIf(condition, E item) { | 157 | void addIf(condition, E item) { |
@@ -161,6 +167,9 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | @@ -161,6 +167,9 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | ||
161 | 167 | ||
162 | operator []=(int index, E value) { | 168 | operator []=(int index, E value) { |
163 | super[index] = value; | 169 | super[index] = value; |
170 | + if (Get.obs != null) { | ||
171 | + Get.obs.addListener(subject.stream); | ||
172 | + } | ||
164 | subject.add(Change<E>.set(item: value, pos: index)); | 173 | subject.add(Change<E>.set(item: value, pos: index)); |
165 | } | 174 | } |
166 | 175 | ||
@@ -196,6 +205,7 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | @@ -196,6 +205,7 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | ||
196 | } | 205 | } |
197 | 206 | ||
198 | close() { | 207 | close() { |
208 | + clear(); | ||
199 | _subscriptions.forEach((observable, subscription) { | 209 | _subscriptions.forEach((observable, subscription) { |
200 | subscription.cancel(); | 210 | subscription.cancel(); |
201 | }); | 211 | }); |
@@ -219,15 +229,13 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | @@ -219,15 +229,13 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | ||
219 | /// A stream of record of changes to this list | 229 | /// A stream of record of changes to this list |
220 | Stream<Change<E>> get onChange { | 230 | Stream<Change<E>> get onChange { |
221 | final now = DateTime.now(); | 231 | final now = DateTime.now(); |
222 | - _changeCtl.addStream(_onChange.skipWhile((m) => m.time.isBefore(now))); | 232 | + |
233 | + _onChange.skipWhile((m) => m.time.isBefore(now)); | ||
223 | return _changeCtl.stream.asBroadcastStream(); | 234 | return _changeCtl.stream.asBroadcastStream(); |
224 | } | 235 | } |
225 | 236 | ||
226 | Stream<Change<E>> _onChange; | 237 | Stream<Change<E>> _onChange; |
227 | 238 | ||
228 | - @override | ||
229 | - StreamController<Change<E>> subject = StreamController<Change<E>>(); | ||
230 | - | ||
231 | addListener(Stream<Change<E>> rxGetx) { | 239 | addListener(Stream<Change<E>> rxGetx) { |
232 | if (_subscriptions.containsKey(rxGetx)) { | 240 | if (_subscriptions.containsKey(rxGetx)) { |
233 | return; | 241 | return; |
@@ -238,7 +246,18 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | @@ -238,7 +246,18 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | ||
238 | } | 246 | } |
239 | 247 | ||
240 | @override | 248 | @override |
241 | - var value; | 249 | + get value { |
250 | + if (Get.obs != null) { | ||
251 | + Get.obs.addListener(subject.stream); | ||
252 | + } | ||
253 | + return this; | ||
254 | + } | ||
255 | + | ||
256 | + // int get length => (value as List).length; | ||
257 | + | ||
258 | + set value(E val) { | ||
259 | + assign(val); | ||
260 | + } | ||
242 | 261 | ||
243 | @override | 262 | @override |
244 | Stream<E> get stream => onChange.map((c) => c.item); | 263 | Stream<E> get stream => onChange.map((c) => c.item); |
@@ -252,7 +271,7 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | @@ -252,7 +271,7 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | ||
252 | void bindStream(Stream<E> stream) => stream.listen((v) => value = v); | 271 | void bindStream(Stream<E> stream) => stream.listen((v) => value = v); |
253 | 272 | ||
254 | @override | 273 | @override |
255 | - void bindOrSet(/* T | Stream<T> | Rx<T> */ other) { | 274 | + void bindOrSet(/* T | Stream<T> or Rx<T> */ other) { |
256 | if (other is RxInterface<E>) { | 275 | if (other is RxInterface<E>) { |
257 | bind(other); | 276 | bind(other); |
258 | } else if (other is Stream<E>) { | 277 | } else if (other is Stream<E>) { |
@@ -267,7 +286,7 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | @@ -267,7 +286,7 @@ class ListX<E> extends DelegatingList<E> implements List<E>, RxInterface<E> { | ||
267 | stream.listen(callback); | 286 | stream.listen(callback); |
268 | 287 | ||
269 | @override | 288 | @override |
270 | - void setCast(dynamic /* T */ val) => value = val; | 289 | + void setCast(dynamic val) => value = val; |
271 | } | 290 | } |
272 | 291 | ||
273 | typedef bool Condition(); | 292 | typedef bool Condition(); |
@@ -275,12 +294,12 @@ typedef bool Condition(); | @@ -275,12 +294,12 @@ typedef bool Condition(); | ||
275 | typedef E ChildrenListComposer<S, E>(S value); | 294 | typedef E ChildrenListComposer<S, E>(S value); |
276 | 295 | ||
277 | /// An observable list that is bound to another list [binding] | 296 | /// An observable list that is bound to another list [binding] |
278 | -class BoundList<S, E> extends ListX<E> { | 297 | +class BindingList<S, E> extends ListX<E> { |
279 | final ListX<S> binding; | 298 | final ListX<S> binding; |
280 | 299 | ||
281 | final ChildrenListComposer<S, E> composer; | 300 | final ChildrenListComposer<S, E> composer; |
282 | 301 | ||
283 | - BoundList(this.binding, this.composer) { | 302 | + BindingList(this.binding, this.composer) { |
284 | for (S v in binding) _add(composer(v)); | 303 | for (S v in binding) _add(composer(v)); |
285 | binding.onChange.listen((Change<S> n) { | 304 | binding.onChange.listen((Change<S> n) { |
286 | if (n.op == ListChangeOp.add) { | 305 | if (n.op == ListChangeOp.add) { |
@@ -6,7 +6,7 @@ abstract class RxInterface<T> { | @@ -6,7 +6,7 @@ abstract class RxInterface<T> { | ||
6 | RxInterface([T initial]); | 6 | RxInterface([T initial]); |
7 | 7 | ||
8 | /// Get current value | 8 | /// Get current value |
9 | - T get value; | 9 | + get value; |
10 | 10 | ||
11 | /// Set value | 11 | /// Set value |
12 | set value(T val); | 12 | set value(T val); |
@@ -15,7 +15,7 @@ abstract class RxInterface<T> { | @@ -15,7 +15,7 @@ abstract class RxInterface<T> { | ||
15 | void setCast(dynamic /* T */ val); | 15 | void setCast(dynamic /* T */ val); |
16 | 16 | ||
17 | /// Stream of record of [Change]s of value | 17 | /// Stream of record of [Change]s of value |
18 | - Stream<Change<T>> get onChange; | 18 | + // Stream<Change<T>> get onChange; |
19 | 19 | ||
20 | /// add listener to stream | 20 | /// add listener to stream |
21 | addListener(Stream<Change<T>> rxGetx); | 21 | addListener(Stream<Change<T>> rxGetx); |
@@ -52,10 +52,10 @@ abstract class RxInterface<T> { | @@ -52,10 +52,10 @@ abstract class RxInterface<T> { | ||
52 | 52 | ||
53 | class RxController implements DisposableInterface { | 53 | class RxController implements DisposableInterface { |
54 | void onInit() async {} | 54 | void onInit() async {} |
55 | - void close() async {} | 55 | + void onClose() async {} |
56 | } | 56 | } |
57 | 57 | ||
58 | abstract class DisposableInterface { | 58 | abstract class DisposableInterface { |
59 | - void close() async {} | 59 | + void onClose() async {} |
60 | void onInit() async {} | 60 | void onInit() async {} |
61 | } | 61 | } |
1 | -import 'dart:async'; | ||
2 | -import 'package:flutter/widgets.dart'; | ||
3 | -import 'package:get/src/get_main.dart'; | ||
4 | -import 'rx_impl.dart'; | ||
5 | -import 'rx_interface.dart'; | 1 | +// import 'dart:async'; |
2 | +// import 'package:flutter/widgets.dart'; | ||
3 | +// import 'package:get/src/get_main.dart'; | ||
4 | +// import 'rx_impl.dart'; | ||
5 | +// import 'rx_interface.dart'; | ||
6 | 6 | ||
7 | -class ListViewX<T extends RxController> extends StatefulWidget { | ||
8 | - final Widget Function(T, int) builder; | ||
9 | - final bool global; | ||
10 | - final ListX Function(T) list; | ||
11 | - final bool autoRemove; | ||
12 | - final void Function(State state) initState, dispose, didChangeDependencies; | ||
13 | - final T init; | ||
14 | - final int itemCount; | ||
15 | - ListViewX({ | ||
16 | - this.builder, | ||
17 | - this.global = true, | ||
18 | - this.autoRemove = true, | ||
19 | - this.initState, | ||
20 | - @required this.list, | ||
21 | - this.itemCount, | ||
22 | - this.dispose, | ||
23 | - this.didChangeDependencies, | ||
24 | - this.init, | ||
25 | - }); | ||
26 | - _ListViewXState<T> createState() => _ListViewXState<T>(); | ||
27 | -} | 7 | +// class ListViewX<T extends RxController> extends StatefulWidget { |
8 | +// final Widget Function(T, int) builder; | ||
9 | +// final bool global; | ||
10 | +// final ListX Function(T) list; | ||
11 | +// final bool autoRemove; | ||
12 | +// final void Function(State state) initState, dispose, didChangeDependencies; | ||
13 | +// final T init; | ||
14 | +// final int itemCount; | ||
15 | +// ListViewX({ | ||
16 | +// this.builder, | ||
17 | +// this.global = true, | ||
18 | +// this.autoRemove = true, | ||
19 | +// this.initState, | ||
20 | +// @required this.list, | ||
21 | +// this.itemCount, | ||
22 | +// this.dispose, | ||
23 | +// this.didChangeDependencies, | ||
24 | +// this.init, | ||
25 | +// }); | ||
26 | +// _ListViewXState<T> createState() => _ListViewXState<T>(); | ||
27 | +// } | ||
28 | 28 | ||
29 | -class _ListViewXState<T extends RxController> extends State<ListViewX<T>> { | ||
30 | - RxInterface _observer; | ||
31 | - StreamSubscription _listenSubscription; | ||
32 | - T controller; | 29 | +// class _ListViewXState<T extends RxController> extends State<ListViewX<T>> { |
30 | +// RxInterface _observer; | ||
31 | +// StreamSubscription _listenSubscription; | ||
32 | +// T controller; | ||
33 | 33 | ||
34 | - _ListViewXState() { | ||
35 | - _observer = ListX(); | ||
36 | - } | 34 | +// _ListViewXState() { |
35 | +// _observer = ListX(); | ||
36 | +// } | ||
37 | 37 | ||
38 | - @override | ||
39 | - void initState() { | ||
40 | - if (widget.global) { | ||
41 | - if (Get.isRegistred<T>()) { | ||
42 | - controller = Get.find<T>(); | ||
43 | - } else { | ||
44 | - controller = widget.init; | ||
45 | - Get.put<T>(controller); | ||
46 | - } | ||
47 | - } else { | ||
48 | - controller = widget.init; | ||
49 | - } | ||
50 | - if (widget.initState != null) widget.initState(this); | ||
51 | - try { | ||
52 | - controller?.onInit(); | ||
53 | - } catch (e) { | ||
54 | - if (Get.isLogEnable) print("Failure on call onInit"); | ||
55 | - } | 38 | +// @override |
39 | +// void initState() { | ||
40 | +// if (widget.global) { | ||
41 | +// if (Get.isRegistred<T>()) { | ||
42 | +// controller = Get.find<T>(); | ||
43 | +// } else { | ||
44 | +// controller = widget.init; | ||
45 | +// Get.put<T>(controller); | ||
46 | +// } | ||
47 | +// } else { | ||
48 | +// controller = widget.init; | ||
49 | +// } | ||
50 | +// if (widget.initState != null) widget.initState(this); | ||
51 | +// try { | ||
52 | +// controller?.onInit(); | ||
53 | +// } catch (e) { | ||
54 | +// if (Get.isLogEnable) print("Failure on call onInit"); | ||
55 | +// } | ||
56 | 56 | ||
57 | - _listenSubscription = widget.list.call(controller).listen((data) { | ||
58 | - setState(() {}); | ||
59 | - }); | ||
60 | - super.initState(); | ||
61 | - } | 57 | +// _listenSubscription = widget.list.call(controller).listen((data) { |
58 | +// setState(() {}); | ||
59 | +// }); | ||
60 | +// super.initState(); | ||
61 | +// } | ||
62 | 62 | ||
63 | - @override | ||
64 | - void dispose() { | ||
65 | - controller?.close(); | ||
66 | - _listenSubscription?.cancel(); | ||
67 | - _observer?.close(); | ||
68 | - super.dispose(); | ||
69 | - } | 63 | +// @override |
64 | +// void dispose() { | ||
65 | +// controller?.onClose(); | ||
66 | +// _listenSubscription?.cancel(); | ||
67 | +// _observer?.close(); | ||
68 | +// super.dispose(); | ||
69 | +// } | ||
70 | 70 | ||
71 | - @override | ||
72 | - Widget build(BuildContext context) { | ||
73 | - _observer.close(); | ||
74 | - final observer = Get.obs; | ||
75 | - Get.obs = this._observer; | ||
76 | - final result = ListView.builder( | ||
77 | - itemCount: widget.itemCount ?? widget.list.call(controller).length, | ||
78 | - itemBuilder: (context, index) { | ||
79 | - return widget.builder(controller, index); | ||
80 | - }); | ||
81 | - Get.obs = observer; | ||
82 | - return result; | ||
83 | - } | ||
84 | -} | 71 | +// @override |
72 | +// Widget build(BuildContext context) { | ||
73 | +// _observer.close(); | ||
74 | +// final observer = Get.obs; | ||
75 | +// Get.obs = this._observer; | ||
76 | +// final result = ListView.builder( | ||
77 | +// itemCount: widget.itemCount ?? widget.list.call(controller).length, | ||
78 | +// itemBuilder: (context, index) { | ||
79 | +// return widget.builder(controller, index); | ||
80 | +// }); | ||
81 | +// Get.obs = observer; | ||
82 | +// return result; | ||
83 | +// } | ||
84 | +// } |
@@ -8,20 +8,22 @@ class RealState { | @@ -8,20 +8,22 @@ class RealState { | ||
8 | } | 8 | } |
9 | 9 | ||
10 | class GetController extends State { | 10 | class GetController extends State { |
11 | - Map<GetController, List<RealState>> _allStates = {}; | 11 | + Map<int, List<RealState>> _allStates = {}; |
12 | 12 | ||
13 | /// Update GetBuilder with update(this) | 13 | /// Update GetBuilder with update(this) |
14 | - void update(GetController controller, [List<String> ids]) { | ||
15 | - if (controller != null) { | 14 | + void update(GetController controller, |
15 | + [List<String> ids, bool condition = true]) { | ||
16 | + if (controller == null || !condition) return; | ||
17 | + | ||
16 | if (ids == null) { | 18 | if (ids == null) { |
17 | - var all = _allStates[controller]; | 19 | + var all = _allStates[controller.hashCode]; |
18 | all.forEach((rs) { | 20 | all.forEach((rs) { |
19 | if (rs.state != null && rs.state.mounted) rs.state.setState(() {}); | 21 | if (rs.state != null && rs.state.mounted) rs.state.setState(() {}); |
20 | }); | 22 | }); |
21 | } else { | 23 | } else { |
22 | ids.forEach( | 24 | ids.forEach( |
23 | (s) { | 25 | (s) { |
24 | - var all = _allStates[controller]; | 26 | + var all = _allStates[controller.hashCode]; |
25 | all.forEach((rs) { | 27 | all.forEach((rs) { |
26 | if (rs.state != null && rs.state.mounted && rs.id == s) | 28 | if (rs.state != null && rs.state.mounted && rs.id == s) |
27 | rs.state.setState(() {}); | 29 | rs.state.setState(() {}); |
@@ -30,9 +32,9 @@ class GetController extends State { | @@ -30,9 +32,9 @@ class GetController extends State { | ||
30 | ); | 32 | ); |
31 | } | 33 | } |
32 | } | 34 | } |
33 | - } | ||
34 | 35 | ||
35 | - void close() {} | 36 | + void onClose() {} |
37 | + void onInit() {} | ||
36 | 38 | ||
37 | @override | 39 | @override |
38 | Widget build(_) => throw ("build method can't be called"); | 40 | Widget build(_) => throw ("build method can't be called"); |
@@ -72,31 +74,31 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | @@ -72,31 +74,31 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | ||
72 | if (widget.global) { | 74 | if (widget.global) { |
73 | if (Get.isRegistred<T>()) { | 75 | if (Get.isRegistred<T>()) { |
74 | controller = Get.find<T>(); | 76 | controller = Get.find<T>(); |
75 | - if (controller._allStates[controller] == null) { | ||
76 | - controller._allStates[controller] = []; | 77 | + if (controller._allStates[controller.hashCode] == null) { |
78 | + controller._allStates[controller.hashCode] = []; | ||
77 | } | 79 | } |
78 | - controller._allStates[controller] | 80 | + controller._allStates[controller.hashCode] |
79 | .add(RealState(state: this, id: widget.id)); | 81 | .add(RealState(state: this, id: widget.id)); |
80 | } else { | 82 | } else { |
81 | controller = widget.init; | 83 | controller = widget.init; |
82 | - if (controller._allStates[controller] == null) { | ||
83 | - controller._allStates[controller] = []; | 84 | + if (controller._allStates[controller.hashCode] == null) { |
85 | + controller._allStates[controller.hashCode] = []; | ||
84 | } | 86 | } |
85 | - controller._allStates[controller] | 87 | + controller._allStates[controller.hashCode] |
86 | .add(RealState(state: this, id: widget.id)); | 88 | .add(RealState(state: this, id: widget.id)); |
87 | Get.put<T>(controller); | 89 | Get.put<T>(controller); |
88 | } | 90 | } |
89 | } else { | 91 | } else { |
90 | controller = widget.init; | 92 | controller = widget.init; |
91 | - if (controller._allStates[controller] == null) { | ||
92 | - controller._allStates[controller] = []; | 93 | + if (controller._allStates[controller.hashCode] == null) { |
94 | + controller._allStates[controller.hashCode] = []; | ||
93 | } | 95 | } |
94 | - controller._allStates[controller] | 96 | + controller._allStates[controller.hashCode] |
95 | .add(RealState(state: this, id: widget.id)); | 97 | .add(RealState(state: this, id: widget.id)); |
96 | } | 98 | } |
97 | if (widget.initState != null) widget.initState(this); | 99 | if (widget.initState != null) widget.initState(this); |
98 | try { | 100 | try { |
99 | - controller?.initState(); | 101 | + controller?.onInit(); |
100 | } catch (e) { | 102 | } catch (e) { |
101 | if (Get.isLogEnable) print("Controller is not attach"); | 103 | if (Get.isLogEnable) print("Controller is not attach"); |
102 | } | 104 | } |
@@ -108,25 +110,25 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | @@ -108,25 +110,25 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | ||
108 | 110 | ||
109 | if (widget.init != null) { | 111 | if (widget.init != null) { |
110 | var b = controller; | 112 | var b = controller; |
111 | - if (b._allStates[controller].hashCode == this.hashCode) { | ||
112 | - b._allStates.remove(controller); | 113 | + if (b._allStates[controller.hashCode].hashCode == this.hashCode) { |
114 | + b._allStates.remove(controller.hashCode); | ||
113 | } | 115 | } |
114 | } else { | 116 | } else { |
115 | var b = controller; | 117 | var b = controller; |
116 | - if (b._allStates[controller].hashCode == this.hashCode) { | ||
117 | - b._allStates.remove(controller); | 118 | + if (b._allStates[controller.hashCode].hashCode == this.hashCode) { |
119 | + b._allStates.remove(controller.hashCode); | ||
118 | } | 120 | } |
119 | } | 121 | } |
120 | if (widget.dispose != null) widget.dispose(this); | 122 | if (widget.dispose != null) widget.dispose(this); |
121 | 123 | ||
122 | if (widget.init != null) { | 124 | if (widget.init != null) { |
123 | if (widget.autoRemove && Get.isRegistred<T>()) { | 125 | if (widget.autoRemove && Get.isRegistred<T>()) { |
124 | - controller.close(); | 126 | + controller.onClose(); |
125 | Get.delete<T>(); | 127 | Get.delete<T>(); |
126 | } | 128 | } |
127 | } else { | 129 | } else { |
128 | // controller._allStates[controller].remove(this); | 130 | // controller._allStates[controller].remove(this); |
129 | - controller._allStates[controller] | 131 | + controller._allStates[controller.hashCode] |
130 | .remove(RealState(state: this, id: widget.id)); | 132 | .remove(RealState(state: this, id: widget.id)); |
131 | } | 133 | } |
132 | } | 134 | } |
@@ -149,3 +151,5 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | @@ -149,3 +151,5 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | ||
149 | return widget.builder(controller); | 151 | return widget.builder(controller); |
150 | } | 152 | } |
151 | } | 153 | } |
154 | + | ||
155 | + |
1 | name: get | 1 | name: get |
2 | description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get. | 2 | description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get. |
3 | -version: 2.5.0 | 3 | +version: 2.5.2 |
4 | homepage: https://github.com/jonataslaw/get | 4 | homepage: https://github.com/jonataslaw/get |
5 | 5 | ||
6 | environment: | 6 | environment: |
-
Please register or login to post a comment