=William Cunha Cardoso

Merge branch 'issue-389' of https://github.com/WilliamCunhaCardoso/getx into issue-389

... ... @@ -22,6 +22,7 @@
- [Gestión del Estado](#gestión-del-estado)
- [Reactivo STATE_MANAGER](#reactivo-state_manager)
- [Más detalles sobre la gestión del estado.](#más-detalles-sobre-la-gestión-del-estado)
- [Video explanation about state management](#video-explanation-about-state-management)
- [Gestión de Rutas](#gestión-de-rutas)
- [Más detalles sobre la gestión de rutas.](#más-detalles-sobre-la-gestión-de-rutas)
- [Video Explanation](#video-explanation)
... ... @@ -31,6 +32,7 @@
- [Cambiar de tema](#cambiar-de-tema)
- [Otras API avanzadas y configuraciones manuales](#otras-api-avanzadas-y-configuraciones-manuales)
- [Configuraciones globales opcionales](#configuraciones-globales-opcionales)
- [Video explanation of Other GetX Features](#video-explanation-of-other-getx-features)
- [Rompiendo cambios desde 2.0](#rompiendo-cambios-desde-20)
- [¿Por qué Getx?](#por-qué-getx)
... ... @@ -187,6 +189,13 @@ Obx(() => Text (controller.name));
**Vea una explicación más detallada de la administración del estado [aquí](./docs/es_ES/state_management.md). Allí verá más ejemplos y también la diferencia entre el Gestión del Estado simple y el Gestión del Estado reactivo**
### Video explanation about state management
Amateur Coder did an awesome video about state management! Link: [Complete GetX State Management](https://www.youtube.com/watch?v=CNpXbeI_slw)
You will get a good idea of GetX power.
## Gestión de Rutas
Para navegar a una nueva pantalla:
... ... @@ -446,6 +455,11 @@ Get.config(
)
```
## Video explanation of Other GetX Features
Amateur Coder did an awesome video about utils, storage, bindings and other features! Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU)
# Rompiendo cambios desde 2.0
1- Rx types:
... ...
... ... @@ -12,26 +12,28 @@
![](getx.png)
- [**Communication and support channels:**](#communication-and-support-channels-)
- [**About Get**](#about-get)
- [**Installing**](#installing)
- [**Counter App in Get**](#counter-app-in-get)
- [**The Three pillars**](#the-three-pillars)
* [State management](#state-management)
+ [Reactive State Manager](#reactive-state-manager)
+ [More details about state management](#more-details-about-state-management)
* [Route management](#route-management)
+ [More details about route management](#more-details-about-route-management)
+ [Video Explanation](#video-explanation)
* [Dependency management](#dependency-management)
+ [More details about dependency management](#more-details-about-dependency-management)
- [**How to contribute**](#how-to-contribute)
- [**Utils**](#utils)
* [Change Theme](#change-theme)
* [Other Advanced APIs](#other-advanced-apis)
+ [Optional Global Settings and Manual configurations](#optional-global-settings-and-manual-configurations)
- [**Breaking changes from 2.0**](#breaking-changes-from-20)
- [**Why Getx?**](#why-getx-)
- [Communication and support channels:](#communication-and-support-channels)
- [About Get](#about-get)
- [Installing](#installing)
- [Counter App with GetX](#counter-app-with-getx)
- [The Three pillars](#the-three-pillars)
- [State management](#state-management)
- [Reactive State Manager](#reactive-state-manager)
- [More details about state management](#more-details-about-state-management)
- [Video explanation about state management](#video-explanation-about-state-management)
- [Route management](#route-management)
- [More details about route management](#more-details-about-route-management)
- [Video Explanation](#video-explanation)
- [Dependency management](#dependency-management)
- [More details about dependency management](#more-details-about-dependency-management)
- [How to contribute](#how-to-contribute)
- [Utils](#utils)
- [Change Theme](#change-theme)
- [Other Advanced APIs](#other-advanced-apis)
- [Optional Global Settings and Manual configurations](#optional-global-settings-and-manual-configurations)
- [Video explanation of Other GetX Features](#video-explanation-of-other-getx-features)
- [Breaking changes from 2.0](#breaking-changes-from-20)
- [Why Getx?](#why-getx)
# Communication and support channels:
... ... @@ -187,7 +189,7 @@ That's all. It's *that* simple.
### Video explanation about state management
Amateur coder did an awesome video about state management! Link: [Complete GetX State Management](https://www.youtube.com/watch?v=CNpXbeI_slw)
Amateur Coder did an awesome video about state management! Link: [Complete GetX State Management](https://www.youtube.com/watch?v=CNpXbeI_slw)
You will get a good idea of GetX power.
... ... @@ -465,12 +467,18 @@ Get.config(
)
```
## Video explanation of Other GetX Features
Amateur Coder did an awesome video about utils, storage, bindings and other features! Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU)
# Breaking changes from 2.0
1- Rx types:
| Before | After |
| -------- | ---------- |
| ------- | ---------- |
| StringX | `RxString` |
| IntX | `RxInt` |
| MapX | `RxMax` |
... ...
... ... @@ -33,6 +33,7 @@
- [Mudar tema (changeTheme)](#mudar-tema-changetheme)
- [Outras APIs avançadas](#outras-apis-avançadas)
- [Configurações Globais opcionais e configurações manuais](#configurações-globais-opcionais-e-configurações-manuais)
- [Video explanation of Other GetX Features](#video-explanation-of-other-getx-features)
- [Breaking Changes da versão 2 para 3](#breaking-changes-da-versão-2-para-3)
- [Tipagem Rx](#tipagem-rx)
- [RxController e GetBuilder se uniram](#rxcontroller-e-getbuilder-se-uniram)
... ... @@ -472,6 +473,11 @@ Get.config(
)
```
## Video explanation of Other GetX Features
Amateur Coder did an awesome video about utils, storage, bindings and other features! Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU)
# Breaking Changes da versão 2 para 3
## Tipagem Rx
... ...
... ... @@ -29,18 +29,31 @@ class GetImpl implements GetService {
RouteSettings settings;
String defaultSeparator = "_";
///Use to instead of Navigator.push, off instead of Navigator.pushReplacement,
///offAll instead of Navigator.pushAndRemoveUntil. For named routes just add "named"
///after them. Example: toNamed, offNamed, and AllNamed.
///To return to the previous screen, use back().
///No need to pass any context to Get, just put the name of the route inside
///the parentheses and the magic will occur.
/// It replaces Navigator.push, but needs no context, and it doesn't have the Navigator.push
/// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
/// of rebuilding every app after a route, use opaque = true as the parameter.
Future<T> to<T>(Widget page,
{bool opaque,
/// Pushes a new [page] to the stack
///
/// It has the advantage of not needing context,
/// so you can call from your business logic
///
/// You can set a custom [transition], and a transition [duration].
///
/// You can send any type of value to the other route in the [arguments].
///
/// Just like native routing in Flutter, you can push a route
/// as a [fullscreenDialog],
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
///
/// If you want the same behavior of ios that pops a route when the user drag,
/// you can set [popGesture] to true
///
/// If you're using the [Bindings] api, you must define it here
///
/// By default, GetX will prevent you from push a route that you already in,
/// if you want to push anyway, set [preventDuplicates] to false
Future<T> to<T>(
Widget page, {
bool opaque,
Transition transition,
Duration duration,
int id,
... ... @@ -48,37 +61,75 @@ class GetImpl implements GetService {
Object arguments,
Bindings binding,
preventDuplicates = true,
bool popGesture}) {
bool popGesture,
}) {
if (preventDuplicates && '/${page.runtimeType}' == currentRoute) {
return null;
}
return global(id).currentState.push(GetPageRoute(
return global(id).currentState.push(
GetPageRoute(
opaque: opaque ?? true,
page: () => page,
settings:
RouteSettings(name: '/${page.runtimeType}', arguments: arguments),
settings: RouteSettings(
name: '/${page.runtimeType}',
arguments: arguments,
),
popGesture: popGesture ?? defaultPopGesture,
transition: transition ?? defaultTransition,
fullscreenDialog: fullscreenDialog,
binding: binding,
transitionDuration: duration ?? defaultDurationTransition));
transitionDuration: duration ?? defaultDurationTransition,
),
);
}
/// It replaces Navigator.pushNamed, but needs no context, and it doesn't have the Navigator.pushNamed
/// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
/// of rebuilding every app after a route, use opaque = true as the parameter.
Future<T> toNamed<T>(String page,
{Object arguments, int id, preventDuplicates = true}) {
/// Pushes a new named [page] to the stack
///
/// It has the advantage of not needing context, so you can call
/// from your business logic.
///
/// You can send any type of value to the other route in the [arguments].
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
///
/// By default, GetX will prevent you from push a route that you already in,
/// if you want to push anyway, set [preventDuplicates] to false
///
/// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
Future<T> toNamed<T>(
String page, {
Object arguments,
int id,
preventDuplicates = true,
}) {
if (preventDuplicates && page == currentRoute) {
return null;
}
return global(id).currentState.pushNamed(page, arguments: arguments);
}
/// It replaces Navigator.pushReplacementNamed, but needs no context.
Future<T> offNamed<T>(String page,
{Object arguments, int id, preventDuplicates = true}) {
/// Pop the current named [page] in the stack and push a new one in its place
///
/// It has the advantage of not needing context, so you can call
/// from your business logic.
///
/// You can send any type of value to the other route in the [arguments].
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
///
/// By default, GetX will prevent you from push a route that you already in,
/// if you want to push anyway, set [preventDuplicates] to false
///
/// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
Future<T> offNamed<T>(
String page, {
Object arguments,
int id,
preventDuplicates = true,
}) {
if (preventDuplicates && page == currentRoute) {
return null;
}
... ... @@ -87,29 +138,72 @@ class GetImpl implements GetService {
.pushReplacementNamed(page, arguments: arguments);
}
/// It replaces Navigator.popUntil, but needs no context.
/// Calls pop several times in the stack until [predicate] returns true
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
///
/// [predicate] can be used like this:
/// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
///
/// or also like this:
/// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
void until(RoutePredicate predicate, {int id}) {
// if (key.currentState.mounted) // add this if appear problems on future with route navigate
// when widget don't mounted
return global(id).currentState.popUntil(predicate);
}
/// It replaces Navigator.pushAndRemoveUntil, but needs no context.
/// Push the given [page], and then pop several [pages] in the stack until
/// [predicate] returns true
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
///
/// [predicate] can be used like this:
/// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
///
/// or also like this:
/// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
Future<T> offUntil<T>(Route<T> page, RoutePredicate predicate, {int id}) {
// if (key.currentState.mounted) // add this if appear problems on future with route navigate
// when widget don't mounted
return global(id).currentState.pushAndRemoveUntil(page, predicate);
}
/// It replaces Navigator.pushNamedAndRemoveUntil, but needs no context.
Future<T> offNamedUntil<T>(String page, RoutePredicate predicate,
{int id, Object arguments}) {
/// Push the given named [page], and then pop several pages in the stack
/// until [predicate] returns true
///
/// You can send any type of value to the other route in the [arguments].
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
///
/// [predicate] can be used like this:
/// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
/// or also like
/// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
///
/// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
Future<T> offNamedUntil<T>(
String page,
RoutePredicate predicate, {
int id,
Object arguments,
}) {
return global(id)
.currentState
.pushNamedAndRemoveUntil(page, predicate, arguments: arguments);
}
/// It replaces Navigator.popAndPushNamed, but needs no context.
/// Pop the current named page and pushes a new [page] to the stack in its place
///
/// You can send any type of value to the other route in the [arguments].
/// It is very similar to `offNamed()` but use a different approach
///
/// The `offNamed()` pop a page, and goes to the next. The `offAndToNamed()` goes
/// to the next page, and removes the previous one. The route transition
/// animation is different.
Future<T> offAndToNamed<T>(String page,
{Object arguments, int id, dynamic result}) {
return global(id)
... ... @@ -117,12 +211,25 @@ class GetImpl implements GetService {
.popAndPushNamed(page, arguments: arguments, result: result);
}
/// It replaces Navigator.removeRoute, but needs no context.
/// Remove a specific [route] from the stack
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
void removeRoute(Route<dynamic> route, {int id}) {
return global(id).currentState.removeRoute(route);
}
/// It replaces Navigator.pushNamedAndRemoveUntil, but needs no context.
/// Push a named [page] and remove all other pages from stack
///
/// It has the advantage of not needing context, so you can
/// call from your business logic.
///
/// You can send any type of value to the other route in the [arguments].
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
///
/// Note: Always put a slash on the route ('/page1'), to avoid unexpected errors
Future<T> offAllNamed<T>(String newRouteName,
{RoutePredicate predicate, Object arguments, int id}) {
var route = (Route<dynamic> rota) => false;
... ... @@ -132,18 +239,30 @@ class GetImpl implements GetService {
arguments: arguments);
}
/// Returns true if a snackbar, dialog or bottomsheet is currently showing in the screen
bool get isOverlaysOpen =>
(isSnackbarOpen || isDialogOpen || isBottomSheetOpen);
/// returns true if there is no snackbar, dialog or bottomsheet open
bool get isOverlaysClosed =>
(!isSnackbarOpen && !isDialogOpen && !isBottomSheetOpen);
/// It replaces Navigator.pop, but needs no context.
void back(
{dynamic result,
/// Pop the current page, snackbar, dialog or bottomsheet in the stack
///
/// if your set [closeOverlays] to true, Get.back() will close the currently open
/// snackbar/dialog/bottomsheet AND the current page
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
///
/// It has the advantage of not needing context, so you can call
/// from your business logic.
void back({
dynamic result,
bool closeOverlays = false,
bool canPop = true,
int id}) {
int id,
}) {
if (closeOverlays && isOverlaysOpen) {
navigator.popUntil((route) {
return (isOverlaysClosed);
... ... @@ -158,7 +277,7 @@ class GetImpl implements GetService {
}
}
/// It will close as many screens as you define. Times must be> 0;
/// Close as many routes as defined by [times]
void close(int times, [int id]) {
if ((times == null) || (times < 1)) {
times = 1;
... ... @@ -170,11 +289,31 @@ class GetImpl implements GetService {
return back;
}
/// It replaces Navigator.pushReplacement, but needs no context, and it doesn't have the Navigator.pushReplacement
/// routes rebuild bug present in Flutter. If for some strange reason you want the default behavior
/// of rebuilding every app after a route, use opaque = true as the parameter.
Future<T> off<T>(Widget page,
{bool opaque = false,
/// Pop the current page and pushes a new [page] to the stack
///
/// It has the advantage of not needing context,
/// so you can call from your business logic
///
/// You can set a custom [transition], and a transition [duration].
///
/// You can send any type of value to the other route in the [arguments].
///
/// Just like native routing in Flutter, you can push a route
/// as a [fullscreenDialog],
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
///
/// If you want the same behavior of ios that pops a route when the user drag,
/// you can set [popGesture] to true
///
/// If you're using the [Bindings] api, you must define it here
///
/// By default, GetX will prevent you from push a route that you already in,
/// if you want to push anyway, set [preventDuplicates] to false
Future<T> off<T>(
Widget page, {
bool opaque = false,
Transition transition,
bool popGesture,
int id,
... ... @@ -182,7 +321,8 @@ class GetImpl implements GetService {
Bindings binding,
bool fullscreenDialog = false,
preventDuplicates = true,
Duration duration}) {
Duration duration,
}) {
if (preventDuplicates && '/${page.runtimeType}' == currentRoute) {
return null;
}
... ... @@ -198,9 +338,36 @@ class GetImpl implements GetService {
transitionDuration: duration ?? defaultDurationTransition));
}
/// It replaces Navigator.pushAndRemoveUntil, but needs no context
Future<T> offAll<T>(Widget page,
{RoutePredicate predicate,
/// Pop all pages in the stack and pushes a new [page] to it
///
/// It has the advantage of not needing context,
/// so you can call from your business logic
///
/// You can set a custom [transition], and a transition [duration].
///
/// You can send any type of value to the other route in the [arguments].
///
/// Just like native routing in Flutter, you can push a route
/// as a [fullscreenDialog],
///
/// [predicate] can be used like this:
/// `Get.until(Get.currentRoute == '/home')`so when you get to home page,
/// or also like
/// `Get.until(!Get.isDialogOpen())`, to make sure the dialog is closed
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
///
/// If you want the same behavior of ios that pops a route when the user drag,
/// you can set [popGesture] to true
///
/// If you're using the [Bindings] api, you must define it here
///
/// By default, GetX will prevent you from push a route that you already in,
/// if you want to push anyway, set [preventDuplicates] to false
Future<T> offAll<T>(
Widget page, {
RoutePredicate predicate,
bool opaque = false,
bool popGesture,
int id,
... ... @@ -208,7 +375,8 @@ class GetImpl implements GetService {
Bindings binding,
bool fullscreenDialog = false,
Duration duration,
Transition transition}) {
Transition transition,
}) {
var route = (Route<dynamic> rota) => false;
return global(id).currentState.pushAndRemoveUntil(
... ... @@ -655,6 +823,16 @@ class GetImpl implements GetService {
translations.addAll(tr);
}
void appendTranslations(Map<String, Map<String, String>> tr) {
tr.forEach((key, map) {
if (Get.translations.containsKey(key)) {
Get.translations[key].addAll(map);
} else {
Get.translations[key] = map;
}
});
}
void changeTheme(ThemeData theme) {
getxController.setTheme(theme);
}
... ...
... ... @@ -257,15 +257,22 @@ abstract class Translations {
extension Trans on String {
String get tr {
// Returns the key if locale is null.
if (Get.locale?.languageCode == null) return this;
if (Get.translations
.containsKey("${Get.locale.languageCode}_${Get.locale.countryCode}")) {
// Checks whether the language code and country code are present, and whether the key is also present.
if (Get.translations.containsKey(
"${Get.locale.languageCode}_${Get.locale.countryCode}") &&
Get.translations["${Get.locale.languageCode}_${Get.locale.countryCode}"]
.containsKey(this)) {
return Get.translations[
"${Get.locale.languageCode}_${Get.locale.countryCode}"][this];
} else if (Get.translations.containsKey(Get.locale.languageCode)) {
// Checks if there is a callback language in the absence of the specific country, and if it contains that key.
} else if (Get.translations.containsKey(Get.locale.languageCode) &&
Get.translations[Get.locale.languageCode].containsKey(this)) {
return Get.translations[Get.locale.languageCode][this];
} else if (Get.translations.isNotEmpty) {
return Get.translations.values.first[this];
// If there is no corresponding language or corresponding key, return the key.
} else {
return this;
}
... ...