Showing
14 changed files
with
216 additions
and
109 deletions
1 | +## [2.11.0] | ||
2 | +- Added Permissions: | ||
3 | +You can now revoke permissions to SmartManagement so that it cannot delete a particular controller. | ||
4 | +Add to Get.put (Controller(), permanent: true); to make it indelible. | ||
5 | +Get.lazyPut () will not receive this resource. Initially he had it, but we saw in internal tests that it could cause problems with the bindings API. Bindings were created to initialize and delete an instance, if it were allowed to make a controller started with lazyPut permanent, copies of that Controller would be created every time Binding was called. For the safety of users, especially new users who could easily do this, it was decided that this feature will only be present in Get.put. | ||
6 | +- Improve: Now a controller's life cycle has no connection with the View life cycle. It is no longer called internally in an "initState", it is now called when the Controller enters memory. This means that now onInit will always be called, regardless of where you started your dependency. | ||
7 | +- removed: this property of the update() method has been permanently removed. | ||
8 | + | ||
1 | ## [2.10.3] | 9 | ## [2.10.3] |
2 | - GetBuilder refactor. 11% reduction in RAM consumption and 2% in CPU consumption for the sample application. (using as base Flutter for linux desktop). | 10 | - GetBuilder refactor. 11% reduction in RAM consumption and 2% in CPU consumption for the sample application. (using as base Flutter for linux desktop). |
3 | 11 |
1 | -<a href="https://www.buymeacoffee.com/jonataslaw" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" align="right" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" > </a> | ||
2 | - | ||
3 |  | 1 |  |
4 | 2 | ||
5 | *Languages: [English](README.md), [Brazilian Portuguese](README.pt-br.md).* | 3 | *Languages: [English](README.md), [Brazilian Portuguese](README.pt-br.md).* |
@@ -10,51 +8,53 @@ | @@ -10,51 +8,53 @@ | ||
10 | <a href="https://github.com/Solido/awesome-flutter"> | 8 | <a href="https://github.com/Solido/awesome-flutter"> |
11 | <img alt="Awesome Flutter" src="https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square" /> | 9 | <img alt="Awesome Flutter" src="https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square" /> |
12 | </a> | 10 | </a> |
11 | +<a href="https://www.buymeacoffee.com/jonataslaw" target="_blank"><img src="https://i.imgur.com/aV6DDA7.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" > </a> | ||
13 | <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> | 12 | <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> |
14 | [](#contributors-) | 13 | [](#contributors-) |
15 | <!-- ALL-CONTRIBUTORS-BADGE:END --> | 14 | <!-- ALL-CONTRIBUTORS-BADGE:END --> |
16 | 15 | ||
17 | 16 | ||
18 | -Get is an extra-light and powerful library for Flutter that will give you superpowers and increase your productivity. Navigate without context, open dialogs, snackbars or bottomsheets from anywhere in your code, Manage states and inject dependencies in an easy and practical way! Get is secure, stable, up-to-date, and offers a huge range of APIs that are not present on default framework. | 17 | +- Get is an extra-light and powerful solution for Flutter. It combines high performance state management, intelligent dependency injection, and route management in a quick and practical way. |
18 | +- Get is not for everyone, its focus is (performance) on the minimum consumption of resources, (productivity) using an easy and pleasant syntax and (organization) allowing the total decoupling of the View from the business logic. | ||
19 | +- Get will save hours of development, and will extract the maximum performance that your application can deliver, being easy for beginners, and accurate for experts. Navigate without context, open dialogs, snackbars or bottomsheets from anywhere in your code, Manage states and inject dependencies in an easy and practical way. Get is secure, stable, up-to-date, and offers a huge range of APIs that are not present on default framework. | ||
19 | 20 | ||
20 | -```dart | ||
21 | -// Default Flutter navigator | ||
22 | -Navigator.of(context).push( | ||
23 | - context, | ||
24 | - MaterialPageRoute( | ||
25 | - builder: (BuildContext context) { | ||
26 | - return Home(); | ||
27 | - }, | ||
28 | - ), | ||
29 | -); | ||
30 | 21 | ||
31 | -// Get syntax | ||
32 | -Get.to(Home()); | ||
33 | -``` | ||
34 | -**Complete example of the Flutter counter app in just 11 lines with Get** | 22 | +**The "counter" project created by default on new project on Flutter has over 100 lines (with comments). To show the power of Get, I will demonstrate how to make a "counter" changing the state with each click, switching between pages and sharing the state between screens, all in an organized way, separating the business logic from the view, in ONLY 26 LINES CODE INCLUDING COMMENTS.** |
35 | 23 | ||
36 | ```dart | 24 | ```dart |
37 | void main() => runApp(GetMaterialApp(home: Home())); | 25 | void main() => runApp(GetMaterialApp(home: Home())); |
26 | +// Create your business logic class and place all variables, methods and controllers inside it. | ||
27 | +class Controller { | ||
28 | + // ".obs" turns any object into an observable one. | ||
29 | + var count = 0.obs; | ||
30 | + increment() => count.value++; | ||
31 | +} | ||
38 | 32 | ||
39 | class Home extends StatelessWidget { | 33 | class Home extends StatelessWidget { |
40 | - final count = 0.obs; | 34 | + // Instantiate your class using Get.put() to make it available for all "child" routes there. |
35 | + final Controller c = Get.put(Controller()); | ||
41 | @override | 36 | @override |
42 | Widget build(context) => Scaffold( | 37 | Widget build(context) => Scaffold( |
43 | - appBar: AppBar(title: Text("Get change you life")), | 38 | + appBar: |
39 | + AppBar(title: Obx(() => Text("Total of clicks: " + c.count.string))), | ||
40 | + // Replace the 8 lines Navigator.push by a simple Get.to(). You don't need context | ||
41 | + body: Center(child: RaisedButton( | ||
42 | + child: Text("Go to Other"), onPressed: () => Get.to(Other()))), | ||
44 | floatingActionButton: | 43 | floatingActionButton: |
45 | - FloatingActionButton(onPressed: () => count.value++), | ||
46 | - body: Center(child: Obx(() => Text(count.string))), | ||
47 | - ); | 44 | + FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment)); |
48 | } | 45 | } |
49 | 46 | ||
50 | -``` | 47 | +class Other extends StatelessWidget { |
48 | + // You can ask Get to find a Controller that is being used by another page and redirect you to it. | ||
49 | + final Controller c = Get.find(); | ||
50 | + @override | ||
51 | + Widget build(context) => Scaffold(body: Center(child: Text(c.count.string))); | ||
52 | +} | ||
51 | 53 | ||
52 | -## Getting Started | 54 | +``` |
53 | 55 | ||
54 | -Flutter's conventional navigation has a lot of unnecessary boilerplate, requires context to navigate between screens, open dialogs, and use snackbars on framework is really boring. | ||
55 | -This library that will change the way you work with the Framework and save your life from boilerplate, increasing your productivity, and provide you with everything that is most modern when it comes to managing states, routes and dependencies. | 56 | +This is a simple project but it already makes clear how powerful Get is. As your project grows, this difference will become more significant. Get was designed to work with teams, but it makes the job of an individual developer simple. Improve your deadlines, deliver everything on time without losing performance. Get is not for everyone, but if you identified with that phrase, Get is for you! |
56 | 57 | ||
57 | -- **[How to use?](#how-to-use)** | ||
58 | - **[Navigating without named routes](#navigating-without-named-routes)** | 58 | - **[Navigating without named routes](#navigating-without-named-routes)** |
59 | - **[SnackBars](#snackBars)** | 59 | - **[SnackBars](#snackBars)** |
60 | - **[Dialogs](#dialogs)** | 60 | - **[Dialogs](#dialogs)** |
@@ -73,7 +73,8 @@ This library that will change the way you work with the Framework and save your | @@ -73,7 +73,8 @@ This library that will change the way you work with the Framework and save your | ||
73 | 73 | ||
74 | 74 | ||
75 | 75 | ||
76 | -#### You can contribute to the project in multiple ways: | 76 | +#### Want to contribute to the project? We will be proud to highlight you as one of our collaborators. Here are some points where you can contribute and make Get (and Flutter) even better. |
77 | + | ||
77 | - Helping to translate the readme into other languages. | 78 | - Helping to translate the readme into other languages. |
78 | - Adding documentation to the readme (not even half of Get's functions have been documented yet). | 79 | - Adding documentation to the readme (not even half of Get's functions have been documented yet). |
79 | - Write articles or make videos teaching how to use Get (they will be inserted in the Readme and in the future in our Wiki). | 80 | - Write articles or make videos teaching how to use Get (they will be inserted in the Readme and in the future in our Wiki). |
@@ -88,12 +89,15 @@ Any contribution is welcome! | @@ -88,12 +89,15 @@ Any contribution is welcome! | ||
88 | - Flutter Stable branch: version 2.0.x | 89 | - Flutter Stable branch: version 2.0.x |
89 | (look for latest version on pub.dev) --> | 90 | (look for latest version on pub.dev) --> |
90 | 91 | ||
91 | -Add Get to your pubspec.yaml file | ||
92 | -<!-- according to the version of Flutter you are using. --> | 92 | +Add this to your pubspec.yaml file: |
93 | + | ||
94 | +``` | ||
95 | +dependencies: | ||
96 | + get: | ||
97 | +``` | ||
98 | +If you are going to use routes/snackbars/dialogs/bottomsheets without context, or use the high-level Get APIs, you need to simply add "Get" before your MaterialApp, turning it into GetMaterialApp and enjoy! | ||
93 | 99 | ||
94 | -Exchange your MaterialApp for GetMaterialApp and enjoy! | ||
95 | ```dart | 100 | ```dart |
96 | -import 'package:get/get.dart'; | ||
97 | GetMaterialApp( // Before: MaterialApp( | 101 | GetMaterialApp( // Before: MaterialApp( |
98 | home: MyHome(), | 102 | home: MyHome(), |
99 | ) | 103 | ) |
@@ -105,7 +109,7 @@ To navigate to a new screen: | @@ -105,7 +109,7 @@ To navigate to a new screen: | ||
105 | Get.to(NextScreen()); | 109 | Get.to(NextScreen()); |
106 | ``` | 110 | ``` |
107 | 111 | ||
108 | -To return to previous screen | 112 | +To close snackbars, dialogs, bottomsheets, or anything you would normally close with Navigator.pop(context); |
109 | 113 | ||
110 | ```dart | 114 | ```dart |
111 | Get.back(); | 115 | Get.back(); |
@@ -130,13 +134,13 @@ var data = await Get.to(Payment()); | @@ -130,13 +134,13 @@ var data = await Get.to(Payment()); | ||
130 | on other screen, send a data for previous route: | 134 | on other screen, send a data for previous route: |
131 | 135 | ||
132 | ```dart | 136 | ```dart |
133 | -Get.back(result: 'sucess'); | 137 | +Get.back(result: 'success'); |
134 | ``` | 138 | ``` |
135 | And use it: | 139 | And use it: |
136 | 140 | ||
137 | ex: | 141 | ex: |
138 | ```dart | 142 | ```dart |
139 | -if(data == 'sucess') madeAnything(); | 143 | +if(data == 'success') madeAnything(); |
140 | ``` | 144 | ``` |
141 | 145 | ||
142 | Don't you want to learn our syntax? | 146 | Don't you want to learn our syntax? |
@@ -331,7 +335,7 @@ class Controller extends GetController { | @@ -331,7 +335,7 @@ class Controller extends GetController { | ||
331 | int counter = 0; | 335 | int counter = 0; |
332 | void increment() { | 336 | void increment() { |
333 | counter++; | 337 | counter++; |
334 | - update(this); // use update(this) to update counter variable on UI when increment be called | 338 | + update(); // use update() to update counter variable on UI when increment be called |
335 | } | 339 | } |
336 | } | 340 | } |
337 | // On your Stateless/Stateful class, use GetBuilder to update Text when increment be called | 341 | // On your Stateless/Stateful class, use GetBuilder to update Text when increment be called |
@@ -379,7 +383,7 @@ class Controller extends GetController { | @@ -379,7 +383,7 @@ class Controller extends GetController { | ||
379 | int counter = 0; | 383 | int counter = 0; |
380 | void increment() { | 384 | void increment() { |
381 | counter++; | 385 | counter++; |
382 | - update(this); | 386 | + update(); |
383 | } | 387 | } |
384 | } | 388 | } |
385 | ``` | 389 | ``` |
@@ -518,12 +522,12 @@ GetBuilder<Controller>( | @@ -518,12 +522,12 @@ GetBuilder<Controller>( | ||
518 | ``` | 522 | ``` |
519 | And update it this form: | 523 | And update it this form: |
520 | ```dart | 524 | ```dart |
521 | -update(this,['text']); | 525 | +update(['text']); |
522 | ``` | 526 | ``` |
523 | You can also impose conditions for the update: | 527 | You can also impose conditions for the update: |
524 | 528 | ||
525 | ```dart | 529 | ```dart |
526 | -update(this,['text'], counter < 10); | 530 | +update(['text'], counter < 10); |
527 | ``` | 531 | ``` |
528 | 532 | ||
529 | GetX does this automatically and only reconstructs the widget that uses the exact variable that was changed, if you change a variable to the same as the previous one and that does not imply a change of state , GetX will not rebuild the widget to save memory and CPU cycles (3 is being displayed on the screen, and you change the variable to 3 again. In most state managers, this will cause a new rebuild, but with GetX the widget will only is rebuilt again, if in fact his state has changed). | 533 | GetX does this automatically and only reconstructs the widget that uses the exact variable that was changed, if you change a variable to the same as the previous one and that does not imply a change of state , GetX will not rebuild the widget to save memory and CPU cycles (3 is being displayed on the screen, and you change the variable to 3 again. In most state managers, this will cause a new rebuild, but with GetX the widget will only is rebuilt again, if in fact his state has changed). |
@@ -535,7 +539,7 @@ You can use both in any situation, but if you want to tune their application to | @@ -535,7 +539,7 @@ You can use both in any situation, but if you want to tune their application to | ||
535 | If you want a powerful state manager, you can go without fear to GetX. It does not work with variables, but flows, everything in it is streams under the hood. You can use rxDart in conjunction with it, because everything is stream, you can hear the event of each "variable", because everything in it is stream, it is literally BLoC, easier than MobX, and without code generator or decorations . | 539 | If you want a powerful state manager, you can go without fear to GetX. It does not work with variables, but flows, everything in it is streams under the hood. You can use rxDart in conjunction with it, because everything is stream, you can hear the event of each "variable", because everything in it is stream, it is literally BLoC, easier than MobX, and without code generator or decorations . |
536 | 540 | ||
537 | 541 | ||
538 | -## Reactive State Manager - GetX | 542 | +## Reactive State Manager |
539 | 543 | ||
540 | If you want power, Get gives you the most advanced state manager you could ever have. | 544 | If you want power, Get gives you the most advanced state manager you could ever have. |
541 | GetX was built 100% based on Streams, and give you all the firepower that BLoC gave you, with an easier facility than using MobX. | 545 | GetX was built 100% based on Streams, and give you all the firepower that BLoC gave you, with an easier facility than using MobX. |
@@ -663,6 +667,21 @@ Obviously, if someone wants to contribute to the project and create a code gener | @@ -663,6 +667,21 @@ Obviously, if someone wants to contribute to the project and create a code gener | ||
663 | Typing in Get using Bindings is unnecessary. you can use the Obx widget instead of GetX which only receives the anonymous function that creates a widget. | 667 | Typing in Get using Bindings is unnecessary. you can use the Obx widget instead of GetX which only receives the anonymous function that creates a widget. |
664 | Obviously, if you don't use a type, you will need to have an instance of your controller to use the variables, or use `Get.find<Controller>()` .value or Controller.to.value to retrieve the value. | 668 | Obviously, if you don't use a type, you will need to have an instance of your controller to use the variables, or use `Get.find<Controller>()` .value or Controller.to.value to retrieve the value. |
665 | 669 | ||
670 | +### GetX vs GetBuilder vs Obx MixinBuilder | ||
671 | +In a decade working with programming I was able to learn some valuable lessons. | ||
672 | +My first contact with reactive programming was so "wow, this is incredible" and in fact reactive programming is incredible. | ||
673 | +However, it is not suitable for all situations. Often all you need is to change the state of 2 or 3 widgets at the same time, or an ephemeral change of state, in which case reactive programming is not bad, but it is not appropriate. | ||
674 | +Reactive programming has a higher consumption of RAM consumption that can be compensated for by the individual workflow, which will ensure that only one widget is rebuilt and when necessary, but creating a list with 80 objects, each with several streams is not a good one idea. Open the dart inspect and check how much a StreamBuilder consumes, and you'll understand what I'm trying to tell you. | ||
675 | +With that in mind, I created the simple state manager. It is simple, and that is exactly what you should demand from it: updating state in blocks in a simple way, and in the most economical way. | ||
676 | +GetBuilder is very economical in RAM, and there is hardly a more economical approach than him (at least I can't imagine one, if it exists, please let us know). | ||
677 | +However, GetBuilder is still a mechanical state manager, you need to call update() just like you would need to call Provider's notifyListeners(). | ||
678 | +There are other situations where reactive programming is really interesting, and not working with it is the same as reinventing the wheel. With that in mind, GetX was created to provide everything that is most modern and advanced in a state manager. It updates only what is necessary and when necessary, if you have an error and send 300 state changes simultaneously, GetX will filter and update the screen only if the state actually changes. | ||
679 | +GetX is still more economical than any other reactive state manager, but it consumes a little more RAM than GetBuilder. Thinking about it and aiming to maximize the consumption of resources that Obx was created. Unlike GetX and GetBuilder, you will not be able to initialize a controller inside an Obx, it is just a Widget with a StreamSubscription that receives change events from your children, that's all. It is more economical than GetX, but loses to GetBuilder, which was to be expected, since it is reactive, and GetBuilder has the most simplistic approach that exists, of storing a widget's hashcode and its StateSetter. With Obx you don't need to write your controller type, and you can hear the change from multiple different controllers, but it needs to be initialized before, either using the example approach at the beginning of this readme, or using the Bindings class. | ||
680 | +Finally, some people opened a resource request, as they wanted to use only one type of reactive variable, and the other mechanics, and needed to insert an Obx into a GetBuilder for this. Thinking about it MixinBuilder was created. It allows both reactive changes by changing ".obs" variables, and mechanical updates via update(). However, of the 4 widgets he is the one that consumes the most resources, since in addition to having a Subscription to receive change events from his children, he subscribes to the update method of his controller. | ||
681 | + | ||
682 | +- Note: To use GetBuilder and MixinBuilder you must use GetController. To use GetX and Obx you must use RxController. | ||
683 | +Probably using a GetController using GetX and Obx will work, but it will not be possible to use an RxController on a GetBuilder. | ||
684 | +Extending these controllers is important, as they have life cycles, and can "start" and "end" events in their onInit() and onClose() methods. | ||
666 | 685 | ||
667 | ## Simple Instance Manager | 686 | ## Simple Instance Manager |
668 | - Note: If you are using Get's State Manager, you don't have to worry about that, just read for information, but pay more attention to the bindings api, which will do all of this automatically for you. | 687 | - Note: If you are using Get's State Manager, you don't have to worry about that, just read for information, but pay more attention to the bindings api, which will do all of this automatically for you. |
@@ -1136,27 +1155,3 @@ Get.contextOverlay // Gives the context of the snackbar/dialog/bottomsheet in th | @@ -1136,27 +1155,3 @@ Get.contextOverlay // Gives the context of the snackbar/dialog/bottomsheet in th | ||
1136 | ``` | 1155 | ``` |
1137 | 1156 | ||
1138 | This library will always be updated and implementing new features. Feel free to offer PRs and contribute to them. | 1157 | This library will always be updated and implementing new features. Feel free to offer PRs and contribute to them. |
1139 | - | ||
1140 | - | ||
1141 | - | ||
1142 | -## Contributors ✨ | ||
1143 | - | ||
1144 | -Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): | ||
1145 | - | ||
1146 | -<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> | ||
1147 | -<!-- prettier-ignore-start --> | ||
1148 | -<!-- markdownlint-disable --> | ||
1149 | -<table> | ||
1150 | - <tr> | ||
1151 | - <td align="center"><a href="https://github.com/jonataslaw"><img src="https://avatars2.githubusercontent.com/u/35742643?v=4" width="100px;" alt=""/><br /><sub><b>Jonny Borges</b></sub></a><br /><a href="https://github.com/jonataslaw/get/commits?author=jonataslaw" title="Code">💻</a></td> | ||
1152 | - <td align="center"><a href="https://github.com/Nipodemos"><img src="https://avatars1.githubusercontent.com/u/11494727?v=4" width="100px;" alt=""/><br /><sub><b>Nipodemos</b></sub></a><br /><a href="https://github.com/jonataslaw/get/commits?author=Nipodemos" title="Documentation">📖</a></td> | ||
1153 | - <td align="center"><a href="https://github.com/RodBr"><img src="https://avatars2.githubusercontent.com/u/13925313?v=4" width="100px;" alt=""/><br /><sub><b>robr</b></sub></a><br /><a href="#tutorial-RodBr" title="Tutorials">✅</a></td> | ||
1154 | - <td align="center"><a href="http://ryanedge.page"><img src="https://avatars1.githubusercontent.com/u/6907797?v=4" width="100px;" alt=""/><br /><sub><b>Ryan</b></sub></a><br /><a href="https://github.com/jonataslaw/get/commits?author=chimon2000" title="Tests">⚠️</a></td> | ||
1155 | - </tr> | ||
1156 | -</table> | ||
1157 | - | ||
1158 | -<!-- markdownlint-enable --> | ||
1159 | -<!-- prettier-ignore-end --> | ||
1160 | -<!-- ALL-CONTRIBUTORS-LIST:END --> | ||
1161 | - | ||
1162 | -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! |
lib/extensions.dart
0 → 100644
1 | +import 'package:flutter/widgets.dart'; | ||
2 | + | ||
3 | +extension MDQ on BuildContext { | ||
4 | + Size get mediaQuerySize => MediaQuery.of(this).size; | ||
5 | + | ||
6 | + double get height => mediaQuerySize.height; | ||
7 | + | ||
8 | + double get width => mediaQuerySize.width; | ||
9 | + | ||
10 | + double heightTransformer({double dividedBy = 1, double reducedBy = 0.0}) { | ||
11 | + return (mediaQuerySize.height - | ||
12 | + ((mediaQuerySize.height / 100) * reducedBy)) / | ||
13 | + dividedBy; | ||
14 | + } | ||
15 | + | ||
16 | + double widthTransformer({double dividedBy = 1, double reducedBy = 0.0}) { | ||
17 | + return (mediaQuerySize.width - ((mediaQuerySize.width / 100) * reducedBy)) / | ||
18 | + dividedBy; | ||
19 | + } | ||
20 | + | ||
21 | + double ratio( | ||
22 | + {double dividedBy = 1, | ||
23 | + double reducedByW = 0.0, | ||
24 | + double reducedByH = 0.0}) { | ||
25 | + return heightTransformer(dividedBy: dividedBy, reducedBy: reducedByH) / | ||
26 | + widthTransformer(dividedBy: dividedBy, reducedBy: reducedByW); | ||
27 | + } | ||
28 | + | ||
29 | + /// similar to MediaQuery.of(this).padding | ||
30 | + EdgeInsets get mediaQueryPadding => MediaQuery.of(this).padding; | ||
31 | + | ||
32 | + /// similar to MediaQuery.of(this).viewPadding | ||
33 | + EdgeInsets get mediaQueryViewPadding => MediaQuery.of(this).viewPadding; | ||
34 | + | ||
35 | + /// similar to MediaQuery.of(this).viewInsets; | ||
36 | + EdgeInsets get mediaQueryViewInsets => MediaQuery.of(this).viewInsets; | ||
37 | + | ||
38 | + /// similar to MediaQuery.of(this).orientation; | ||
39 | + Orientation get orientation => MediaQuery.of(this).orientation; | ||
40 | + | ||
41 | + /// check if device is on landscape mode | ||
42 | + bool get isLandscape => orientation == Orientation.landscape; | ||
43 | + | ||
44 | + /// check if device is on portrait mode | ||
45 | + bool get isPortrait => orientation == Orientation.portrait; | ||
46 | + | ||
47 | + /// similar to MediaQuery.of(this).devicePixelRatio; | ||
48 | + double get devicePixelRatio => MediaQuery.of(this).devicePixelRatio; | ||
49 | + | ||
50 | + /// similar to MediaQuery.of(this).textScaleFactor; | ||
51 | + double get textScaleFactor => MediaQuery.of(this).textScaleFactor; | ||
52 | + | ||
53 | + /// get the shortestSide from screen | ||
54 | + double get mediaQueryShortestSide => mediaQuerySize.shortestSide; | ||
55 | + | ||
56 | + /// True if width be larger than 800 | ||
57 | + bool get showNavbar => (width > 800); | ||
58 | + | ||
59 | + /// True if the shortestSide is smaller than 600p | ||
60 | + bool get isPhone => (mediaQueryShortestSide < 600); | ||
61 | + | ||
62 | + /// True if the shortestSide is largest than 600p | ||
63 | + bool get isSmallTablet => (mediaQueryShortestSide >= 600); | ||
64 | + | ||
65 | + /// True if the shortestSide is largest than 720p | ||
66 | + bool get isLargeTablet => (mediaQueryShortestSide >= 720); | ||
67 | + | ||
68 | + /// True if the current device is Tablet | ||
69 | + bool get isTablet => isSmallTablet || isLargeTablet; | ||
70 | +} |
@@ -19,3 +19,4 @@ export 'src/routes/bindings_interface.dart'; | @@ -19,3 +19,4 @@ export 'src/routes/bindings_interface.dart'; | ||
19 | export 'src/routes/observers/route_observer.dart'; | 19 | export 'src/routes/observers/route_observer.dart'; |
20 | export 'src/routes/transitions_type.dart'; | 20 | export 'src/routes/transitions_type.dart'; |
21 | export 'src/platform/platform.dart'; | 21 | export 'src/platform/platform.dart'; |
22 | + |
@@ -4,6 +4,7 @@ import 'package:get/get.dart'; | @@ -4,6 +4,7 @@ import 'package:get/get.dart'; | ||
4 | import 'bottomsheet/bottomsheet.dart'; | 4 | import 'bottomsheet/bottomsheet.dart'; |
5 | import 'platform/platform.dart'; | 5 | import 'platform/platform.dart'; |
6 | import 'root/root_controller.dart'; | 6 | import 'root/root_controller.dart'; |
7 | +import 'root/smart_management.dart'; | ||
7 | import 'routes/bindings_interface.dart'; | 8 | import 'routes/bindings_interface.dart'; |
8 | import 'routes/default_route.dart'; | 9 | import 'routes/default_route.dart'; |
9 | import 'routes/observers/route_observer.dart'; | 10 | import 'routes/observers/route_observer.dart'; |
@@ -657,6 +658,7 @@ class Get { | @@ -657,6 +658,7 @@ class Get { | ||
657 | static S put<S>( | 658 | static S put<S>( |
658 | S dependency, { | 659 | S dependency, { |
659 | String tag, | 660 | String tag, |
661 | + bool permanent = false, | ||
660 | bool overrideAbstract = false, | 662 | bool overrideAbstract = false, |
661 | _FcBuilderFunc<S> builder, | 663 | _FcBuilderFunc<S> builder, |
662 | }) { | 664 | }) { |
@@ -665,6 +667,7 @@ class Get { | @@ -665,6 +667,7 @@ class Get { | ||
665 | replace: overrideAbstract, | 667 | replace: overrideAbstract, |
666 | //?? (("$S" == "${dependency.runtimeType}") == false), | 668 | //?? (("$S" == "${dependency.runtimeType}") == false), |
667 | name: tag, | 669 | name: tag, |
670 | + permanent: permanent, | ||
668 | builder: builder ?? (() => dependency)); | 671 | builder: builder ?? (() => dependency)); |
669 | return find<S>(tag: tag); | 672 | return find<S>(tag: tag); |
670 | } | 673 | } |
@@ -686,14 +689,16 @@ class Get { | @@ -686,14 +689,16 @@ class Get { | ||
686 | bool isSingleton, | 689 | bool isSingleton, |
687 | String name, | 690 | String name, |
688 | bool replace = true, | 691 | bool replace = true, |
692 | + bool permanent = false, | ||
689 | _FcBuilderFunc<S> builder, | 693 | _FcBuilderFunc<S> builder, |
690 | }) { | 694 | }) { |
691 | assert(builder != null); | 695 | assert(builder != null); |
692 | String key = _getKey(S, name); | 696 | String key = _getKey(S, name); |
693 | if (replace) { | 697 | if (replace) { |
694 | - Get()._singl[key] = _FcBuilder<S>(isSingleton, builder); | 698 | + Get()._singl[key] = _FcBuilder<S>(isSingleton, builder, permanent); |
695 | } else { | 699 | } else { |
696 | - Get()._singl.putIfAbsent(key, () => _FcBuilder<S>(isSingleton, builder)); | 700 | + Get()._singl.putIfAbsent( |
701 | + key, () => _FcBuilder<S>(isSingleton, builder, permanent)); | ||
697 | } | 702 | } |
698 | } | 703 | } |
699 | 704 | ||
@@ -734,12 +739,24 @@ class Get { | @@ -734,12 +739,24 @@ class Get { | ||
734 | return Get()._singl[key].getSependency(); | 739 | return Get()._singl[key].getSependency(); |
735 | } | 740 | } |
736 | 741 | ||
742 | + void initController<S>({String tag}) { | ||
743 | + String key = _getKey(S, tag); | ||
744 | + final i = Get()._singl[key].getSependency(); | ||
745 | + | ||
746 | + if (i is DisposableInterface) { | ||
747 | + i.onInit(); | ||
748 | + if (isLogEnable) print('[GET] $key has been initialized'); | ||
749 | + } | ||
750 | + } | ||
751 | + | ||
737 | /// Find a instance from required class | 752 | /// Find a instance from required class |
738 | static S find<S>({String tag, _FcBuilderFunc<S> instance}) { | 753 | static S find<S>({String tag, _FcBuilderFunc<S> instance}) { |
739 | String key = _getKey(S, tag); | 754 | String key = _getKey(S, tag); |
755 | + bool callInit = false; | ||
740 | if (Get.isRegistred<S>(tag: tag)) { | 756 | if (Get.isRegistred<S>(tag: tag)) { |
741 | if (!isDependencyInit<S>()) { | 757 | if (!isDependencyInit<S>()) { |
742 | Get().registerRouteInstance<S>(tag: tag); | 758 | Get().registerRouteInstance<S>(tag: tag); |
759 | + callInit = true; | ||
743 | } | 760 | } |
744 | 761 | ||
745 | _FcBuilder builder = Get()._singl[key]; | 762 | _FcBuilder builder = Get()._singl[key]; |
@@ -750,6 +767,10 @@ class Get { | @@ -750,6 +767,10 @@ class Get { | ||
750 | throw "class ${S.toString()} with tag '$tag' is not register"; | 767 | throw "class ${S.toString()} with tag '$tag' is not register"; |
751 | } | 768 | } |
752 | } | 769 | } |
770 | + if (callInit) { | ||
771 | + Get().initController<S>(tag: tag); | ||
772 | + } | ||
773 | + | ||
753 | return Get()._singl[key].getSependency(); | 774 | return Get()._singl[key].getSependency(); |
754 | } else { | 775 | } else { |
755 | if (!Get()._factory.containsKey(key)) | 776 | if (!Get()._factory.containsKey(key)) |
@@ -760,12 +781,17 @@ class Get { | @@ -760,12 +781,17 @@ class Get { | ||
760 | 781 | ||
761 | if (!isDependencyInit<S>()) { | 782 | if (!isDependencyInit<S>()) { |
762 | Get().registerRouteInstance<S>(tag: tag); | 783 | Get().registerRouteInstance<S>(tag: tag); |
784 | + callInit = true; | ||
763 | } | 785 | } |
764 | 786 | ||
765 | if (Get().smartManagement != SmartManagement.keepFactory) { | 787 | if (Get().smartManagement != SmartManagement.keepFactory) { |
766 | Get()._factory.remove(key); | 788 | Get()._factory.remove(key); |
767 | } | 789 | } |
768 | 790 | ||
791 | + if (callInit) { | ||
792 | + Get().initController<S>(tag: tag); | ||
793 | + } | ||
794 | + | ||
769 | return _value; | 795 | return _value; |
770 | } | 796 | } |
771 | } | 797 | } |
@@ -815,6 +841,14 @@ class Get { | @@ -815,6 +841,14 @@ class Get { | ||
815 | } | 841 | } |
816 | 842 | ||
817 | _FcBuilder builder = Get()._singl[newKey]; | 843 | _FcBuilder builder = Get()._singl[newKey]; |
844 | + if (builder.permanent) { | ||
845 | + (key == null) | ||
846 | + ? print( | ||
847 | + '[GET] [$newKey] has been marked as permanent, SmartManagement is not authorized to delete it.') | ||
848 | + : print( | ||
849 | + '[GET] [$newKey] has been marked as permanent, SmartManagement is not authorized to delete it.'); | ||
850 | + return false; | ||
851 | + } | ||
818 | final i = builder.dependency; | 852 | final i = builder.dependency; |
819 | 853 | ||
820 | if (i is DisposableInterface || i is GetController) { | 854 | if (i is DisposableInterface || i is GetController) { |
@@ -953,8 +987,9 @@ class _FcBuilder<S> { | @@ -953,8 +987,9 @@ class _FcBuilder<S> { | ||
953 | bool isSingleton; | 987 | bool isSingleton; |
954 | _FcBuilderFunc builderFunc; | 988 | _FcBuilderFunc builderFunc; |
955 | S dependency; | 989 | S dependency; |
990 | + bool permanent = false; | ||
956 | 991 | ||
957 | - _FcBuilder(this.isSingleton, this.builderFunc); | 992 | + _FcBuilder(this.isSingleton, this.builderFunc, this.permanent); |
958 | 993 | ||
959 | S getSependency() { | 994 | S getSependency() { |
960 | if (isSingleton) { | 995 | if (isSingleton) { |
@@ -968,13 +1003,6 @@ class _FcBuilder<S> { | @@ -968,13 +1003,6 @@ class _FcBuilder<S> { | ||
968 | } | 1003 | } |
969 | } | 1004 | } |
970 | 1005 | ||
971 | -enum SmartManagement { | ||
972 | - full, | ||
973 | - onlyBuilder, | ||
974 | - keepFactory, | ||
975 | - // none, | ||
976 | -} | ||
977 | - | ||
978 | typedef _FcBuilderFunc<S> = S Function(); | 1006 | typedef _FcBuilderFunc<S> = S Function(); |
979 | 1007 | ||
980 | typedef _FcBuilderFuncAsync<S> = Future<S> Function(); | 1008 | typedef _FcBuilderFuncAsync<S> = Future<S> Function(); |
@@ -19,7 +19,6 @@ class GetMaterialController extends GetController { | @@ -19,7 +19,6 @@ class GetMaterialController extends GetController { | ||
19 | } | 19 | } |
20 | 20 | ||
21 | void restartApp() { | 21 | void restartApp() { |
22 | - print("restart chamado"); | ||
23 | key = UniqueKey(); | 22 | key = UniqueKey(); |
24 | update(); | 23 | update(); |
25 | } | 24 | } |
@@ -3,6 +3,7 @@ import 'package:get/get.dart'; | @@ -3,6 +3,7 @@ import 'package:get/get.dart'; | ||
3 | import 'package:get/src/routes/get_route.dart'; | 3 | import 'package:get/src/routes/get_route.dart'; |
4 | import 'package:get/src/routes/utils/parse_arguments.dart'; | 4 | import 'package:get/src/routes/utils/parse_arguments.dart'; |
5 | import 'root_controller.dart'; | 5 | import 'root_controller.dart'; |
6 | +import 'smart_management.dart'; | ||
6 | 7 | ||
7 | class GetMaterialApp extends StatelessWidget { | 8 | class GetMaterialApp extends StatelessWidget { |
8 | const GetMaterialApp({ | 9 | const GetMaterialApp({ |
lib/src/root/smart_management.dart
0 → 100644
@@ -4,7 +4,7 @@ import 'package:get/src/get_main.dart'; | @@ -4,7 +4,7 @@ import 'package:get/src/get_main.dart'; | ||
4 | import 'rx_impl.dart'; | 4 | import 'rx_impl.dart'; |
5 | import 'rx_interface.dart'; | 5 | import 'rx_interface.dart'; |
6 | 6 | ||
7 | -class GetX<T extends RxController> extends StatefulWidget { | 7 | +class GetX<T extends DisposableInterface> extends StatefulWidget { |
8 | final Widget Function(T) builder; | 8 | final Widget Function(T) builder; |
9 | final bool global; | 9 | final bool global; |
10 | // final Stream Function(T) stream; | 10 | // final Stream Function(T) stream; |
@@ -28,7 +28,7 @@ class GetX<T extends RxController> extends StatefulWidget { | @@ -28,7 +28,7 @@ class GetX<T extends RxController> extends StatefulWidget { | ||
28 | _GetXState<T> createState() => _GetXState<T>(); | 28 | _GetXState<T> createState() => _GetXState<T>(); |
29 | } | 29 | } |
30 | 30 | ||
31 | -class _GetXState<T extends RxController> extends State<GetX<T>> { | 31 | +class _GetXState<T extends DisposableInterface> extends State<GetX<T>> { |
32 | RxInterface _observer; | 32 | RxInterface _observer; |
33 | StreamSubscription _listenSubscription; | 33 | StreamSubscription _listenSubscription; |
34 | T controller; | 34 | T controller; |
@@ -60,11 +60,12 @@ class _GetXState<T extends RxController> extends State<GetX<T>> { | @@ -60,11 +60,12 @@ class _GetXState<T extends RxController> extends State<GetX<T>> { | ||
60 | } else { | 60 | } else { |
61 | controller = widget.init; | 61 | controller = widget.init; |
62 | isCreator = true; | 62 | isCreator = true; |
63 | - } | ||
64 | - if (widget.initState != null) widget.initState(this); | ||
65 | - if (isCreator) { | ||
66 | controller?.onInit(); | 63 | controller?.onInit(); |
67 | } | 64 | } |
65 | + if (widget.initState != null) widget.initState(this); | ||
66 | + // if (isCreator) { | ||
67 | + // controller?.onInit(); | ||
68 | + // } | ||
68 | 69 | ||
69 | _listenSubscription = _observer.subject.stream.listen((data) { | 70 | _listenSubscription = _observer.subject.stream.listen((data) { |
70 | setState(() {}); | 71 | setState(() {}); |
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | import 'package:flutter/widgets.dart'; | 2 | import 'package:flutter/widgets.dart'; |
3 | +import 'package:get/src/rx/rx_interface.dart'; | ||
3 | import '../get_main.dart'; | 4 | import '../get_main.dart'; |
4 | 5 | ||
5 | -class GetController { | 6 | +class GetController extends DisposableInterface { |
6 | void onClose() async {} | 7 | void onClose() async {} |
7 | void onInit() async {} | 8 | void onInit() async {} |
8 | List<RealState> _allStates = []; | 9 | List<RealState> _allStates = []; |
9 | 10 | ||
10 | /// Update GetBuilder with update(); | 11 | /// Update GetBuilder with update(); |
11 | - void update( | ||
12 | - [@Deprecated('Instead of using the "update(this)" use only "update()". The "this" property will be removed in the next update') | ||
13 | - GetController _this, | ||
14 | - List<String> ids, | ||
15 | - bool condition = true]) { | 12 | + void update([List<String> ids, bool condition = true]) { |
16 | if (!condition) return; | 13 | if (!condition) return; |
17 | 14 | ||
18 | if (ids == null) { | 15 | if (ids == null) { |
@@ -97,11 +94,12 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | @@ -97,11 +94,12 @@ class _GetBuilderState<T extends GetController> extends State<GetBuilder<T>> { | ||
97 | isCreator = true; | 94 | isCreator = true; |
98 | real = RealState(updater: setState, id: widget.id); | 95 | real = RealState(updater: setState, id: widget.id); |
99 | controller._allStates.add(real); | 96 | controller._allStates.add(real); |
100 | - } | ||
101 | - if (widget.initState != null) widget.initState(this); | ||
102 | - if (isCreator) { | ||
103 | controller?.onInit(); | 97 | controller?.onInit(); |
104 | } | 98 | } |
99 | + if (widget.initState != null) widget.initState(this); | ||
100 | + // if (isCreator) { | ||
101 | + // controller?.onInit(); | ||
102 | + // } | ||
105 | } | 103 | } |
106 | 104 | ||
107 | @override | 105 | @override |
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.10.3 | 3 | +version: 2.11.0 |
4 | homepage: https://github.com/jonataslaw/get | 4 | homepage: https://github.com/jonataslaw/get |
5 | 5 | ||
6 | environment: | 6 | environment: |
@@ -18,18 +18,18 @@ void main() { | @@ -18,18 +18,18 @@ void main() { | ||
18 | child: Text("increment"), | 18 | child: Text("increment"), |
19 | onPressed: () => controller.increment(), | 19 | onPressed: () => controller.increment(), |
20 | ), | 20 | ), |
21 | - // FlatButton( | ||
22 | - // child: Text("incrementWithId"), | ||
23 | - // onPressed: () => controller.incrementWithId(), | ||
24 | - // ), | ||
25 | - // GetBuilder<Controller>( | ||
26 | - // id: '1', | ||
27 | - // didChangeDependencies: (_) { | ||
28 | - // print("didChangeDependencies called"); | ||
29 | - // }, | ||
30 | - // builder: (controller) { | ||
31 | - // return Text('id ${controller.counter}'); | ||
32 | - // }), | 21 | + FlatButton( |
22 | + child: Text("incrementWithId"), | ||
23 | + onPressed: () => controller.incrementWithId(), | ||
24 | + ), | ||
25 | + GetBuilder<Controller>( | ||
26 | + id: '1', | ||
27 | + didChangeDependencies: (_) { | ||
28 | + print("didChangeDependencies called"); | ||
29 | + }, | ||
30 | + builder: (controller) { | ||
31 | + return Text('id ${controller.counter}'); | ||
32 | + }), | ||
33 | GetBuilder<Controller2>(builder: (controller) { | 33 | GetBuilder<Controller2>(builder: (controller) { |
34 | return Text('lazy ${controller.test}'); | 34 | return Text('lazy ${controller.test}'); |
35 | }), | 35 | }), |
@@ -59,11 +59,11 @@ void main() { | @@ -59,11 +59,11 @@ void main() { | ||
59 | 59 | ||
60 | expect(find.text("2"), findsOneWidget); | 60 | expect(find.text("2"), findsOneWidget); |
61 | 61 | ||
62 | - // await test.tap(find.text('incrementWithId')); | 62 | + await test.tap(find.text('incrementWithId')); |
63 | 63 | ||
64 | await test.pump(); | 64 | await test.pump(); |
65 | 65 | ||
66 | - // expect(find.text("id 3"), findsOneWidget); | 66 | + expect(find.text("id 3"), findsOneWidget); |
67 | expect(find.text("lazy 0"), findsOneWidget); | 67 | expect(find.text("lazy 0"), findsOneWidget); |
68 | expect(find.text("single 0"), findsOneWidget); | 68 | expect(find.text("single 0"), findsOneWidget); |
69 | }); | 69 | }); |
@@ -90,10 +90,10 @@ class Controller extends GetController { | @@ -90,10 +90,10 @@ class Controller extends GetController { | ||
90 | update(); | 90 | update(); |
91 | } | 91 | } |
92 | 92 | ||
93 | - // void incrementWithId() { | ||
94 | - // counter++; | ||
95 | - // update(this, ['1']); | ||
96 | - // } | 93 | + void incrementWithId() { |
94 | + counter++; | ||
95 | + update(['1']); | ||
96 | + } | ||
97 | } | 97 | } |
98 | 98 | ||
99 | class Controller2 extends GetController { | 99 | class Controller2 extends GetController { |
-
Please register or login to post a comment