Renat Fakhrutdinov
Committed by GitHub

Merge pull request #11 from jonataslaw/master

update
Showing 48 changed files with 499 additions and 318 deletions
... ... @@ -12,6 +12,29 @@ assignees: jonataslaw
**Describe the bug**
A clear and concise description of what the bug is.
**Reproduction code
NOTE: THIS IS MANDATORY, IF YOUR ISSUE DOES NOT CONTAIN IT, IT WILL BE CLOSED PRELIMINARY)**
example:
```dart
void main() => runApp(MaterialApp(home: Home()));
class Home extends StatelessWidget {
final count = 0.obs;
@override
Widget build(context) => Scaffold(
appBar: AppBar(title: Text("counter")),
body: Center(
child: Obx(() => Text("$count")),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => count.value++,
));
}
```
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
... ...
... ... @@ -219,7 +219,7 @@ void main() {
Send data on route name
```dart
Get.toNamed("/second/34954");
Get.toNamed("/profile/34954");
```
On second screen take the data by parameter
... ...
... ... @@ -357,7 +357,7 @@ class User() {
// on the controller file
final user = User().obs;
// when you need to update the user variable:
user.update( (user) { // this parameter is the class itself taht you want to update
user.update( (user) { // this parameter is the class itself that you want to update
user.name = 'Jonny';
user.age = 18;
});
... ...
## [3.12.1]
- Remove spaces whitespaces from dart files
## [3.12.0]
- Added BottomSheet Duration && Export SingleGetTickerProvider (@unacorbatanegra)
- Improve docs from dependencies management (@ngxingyu)
- Fix unknownRoute with null Custom Transition (@marcosfons)
- Optimize capitalize method (@zl910627)
- Added Chinese documentation (@idootop)
- Added TextDirection property on GetMaterialApp to improve RTL layout (@justkawal)
- Remove unnecessary files on git (@nipodemos)
- Fix tags on Get.create() and GetWidget() (@roipeker)
- Update mockito dependency on getTests
- Added GetStatelessWidget, a StatelessWidget base to GetWidget with lifecycle control of controllers. Note: It's a base class, you don't need change to use it or change your GetView, GetWidget StatelessWidget to It.
## [3.11.1]
- Fix docs
... ...
MIT License
Copyright (c) 2019 Jonny Borges
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
package getx.demo.app.example
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity() {
}
/// GetX is an extra-light and powerful multiplatform framework.
/// It combines high performance state management, intelligent dependency
/// injection, and route management in a quick and practical way.
library get;
export 'package:get_core/get_core.dart';
... ...
library get;
/// Get Instance Manager is a modern and intelligent dependency injector
/// that injects and removes dependencies seasonally.
library instance_manager;
export 'package:get_instance/get_instance.dart';
... ...
library get;
///Get Navigator allows you to navigate routes, open snackbars,
///dialogs and bottomsheets easily, and without the need for context.
library route_manager;
export 'package:get_navigation/get_navigation.dart';
... ...
library get;
/// Get State Manager is a light, modern and powerful state manager to Flutter
library state_manager;
export 'package:get_rx/get_rx.dart';
export 'package:get_state_manager/get_state_manager.dart';
... ...
library get;
/// Get utils is a set of tools that allows you to access high-level
/// APIs and obtain validation tools for Flutter and GetX
library utils;
export 'package:get_utils/get_utils.dart';
... ...
name: get
description: Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with GetX.
version: 3.11.1
version: 3.12.1
homepage: https://github.com/jonataslaw/getx
environment:
... ...
## [3.12.0]
* Bump to Get 3.12.0
## [3.10.2]
* Initial release
... ...
name: get_core
description: A base package from allow use resources from GetX™ framework.
version: 3.10.2
version: 3.12.0
homepage: https://github.com/jonataslaw/getx
environment:
... ...
## [3.12.0]
* Bump to Get 3.12.0
## [3.10.2]
- Initial release
... ...
... ... @@ -2,4 +2,4 @@ export 'package:get_core/get_core.dart';
export 'src/bindings_interface.dart';
export 'src/extension_instance.dart';
export 'src/get_instance.dart';
export 'src/lifecircle.dart';
export 'src/lifecycle.dart';
... ...
... ... @@ -27,7 +27,7 @@ abstract class Bindings {
/// ```
class BindingsBuilder<T> extends Bindings {
/// Register your dependencies in the [builder] callback.
final VoidCallback builder;
final BindingBuilderCallback builder;
/// Shortcut to register 1 Controller with Get.put(),
/// Prevents the issue of the fat arrow function with the constructor.
... ... @@ -62,4 +62,4 @@ class BindingsBuilder<T> extends Bindings {
// typedef Snack = Function();
// typedef Modal = Function();
// typedef Route = Function();
typedef VoidCallback = void Function();
typedef BindingBuilderCallback = void Function();
... ...
... ... @@ -3,7 +3,7 @@ import 'dart:collection';
import 'package:get_core/get_core.dart';
import 'lifecircle.dart';
import 'lifecycle.dart';
class GetInstance {
factory GetInstance() => _getInstance ??= GetInstance._();
... ... @@ -12,8 +12,6 @@ class GetInstance {
static GetInstance _getInstance;
// static final config = Get();
/// Holds references to every registered Instance when using
/// [Get.put()]
static final Map<String, _InstanceBuilderFactory> _singl = {};
... ... @@ -142,7 +140,7 @@ class GetInstance {
/// using [Get.smartManagement] as [SmartManagement.full] or
/// [SmartManagement.keepFactory]
/// Meant for internal usage of [GetPageRoute] and [GetDialogRoute]
Future<void> removeDependencyByRoute(String routeName) async {
void removeDependencyByRoute(String routeName) {
final keysToRemove = <String>[];
_routesKey.forEach((key, value) {
if (value == routeName) {
... ... @@ -156,7 +154,7 @@ class GetInstance {
// assure the [DisposableInterface] instance holding a reference
// to [onClose()] wasn't disposed.
if (onClose != null) {
await onClose();
onClose();
}
}
_routesByCreate[routeName].clear();
... ... @@ -164,7 +162,7 @@ class GetInstance {
}
for (final element in keysToRemove) {
await delete(key: element);
delete(key: element);
}
for (final element in keysToRemove) {
... ... @@ -227,26 +225,26 @@ class GetInstance {
return i;
}
// S putOrFind<S>(S Function() dep, {String tag}) {
// final key = _getKey(S, tag);
S putOrFind<S>(InstanceBuilderCallback<S> dep, {String tag}) {
final key = _getKey(S, tag);
// if (_singl.containsKey(key)) {
// return _singl[key].getDependency() as S;
// } else {
// if (_factory.containsKey(key)) {
// S _value = put<S>((_factory[key].builder() as S), tag: tag);
if (_singl.containsKey(key)) {
return _singl[key].getDependency() as S;
} else {
if (_factory.containsKey(key)) {
final _value = put<S>((_factory[key].builder() as S), tag: tag);
// if (Get.smartManagement != SmartManagement.keepFactory) {
// if (!_factory[key].fenix) {
// _factory.remove(key);
// }
// }
// return _value;
// }
if (Get.smartManagement != SmartManagement.keepFactory) {
if (!_factory[key].fenix) {
_factory.remove(key);
}
}
return _value;
}
// return GetInstance().put(dep(), tag: tag);
// }
// }
return GetInstance().put(dep(), tag: tag);
}
}
/// Finds the registered type <[S]> (or [tag])
/// In case of using Get.[create] to register a type <[S]> or [tag],
... ... @@ -258,9 +256,9 @@ class GetInstance {
if (isRegistered<S>(tag: tag)) {
if (_singl[key] == null) {
if (tag == null) {
throw 'Class "$S" is not register';
throw 'Class "$S" is not registered';
} else {
throw 'Class "$S" with tag "$tag" is not register';
throw 'Class "$S" with tag "$tag" is not registered';
}
}
... ... @@ -307,16 +305,6 @@ class GetInstance {
return true;
}
// Future<bool> delete<S>({
// String tag,
// String key,
// bool force = false,
// }) async {
// final s = await queue
// .add<bool>(() async => dele<S>(tag: tag, key: key, force: force));
// return s;
// }
/// Delete registered Class Instance [S] (or [tag]) and, closes any open
/// controllers [DisposableInterface], cleans up the memory
///
... ... @@ -333,7 +321,13 @@ class GetInstance {
/// - [key] For internal usage, is the processed key used to register
/// the Instance. **don't use** it unless you know what you are doing.
/// - [force] Will delete an Instance even if marked as [permanent].
Future<bool> delete<S>({String tag, String key, bool force = false}) async {
bool delete<S>({String tag, String key, bool force = false}) {
// return _queue.secure<bool>(() {
return _delete<S>(tag: tag, key: key, force: force);
// });
}
bool _delete<S>({String tag, String key, bool force = false}) {
final newKey = key ?? _getKey(S, tag);
if (!_singl.containsKey(newKey)) {
... ... @@ -356,7 +350,7 @@ class GetInstance {
return false;
}
if (i is GetLifeCycle) {
await i.onClose();
i.onClose();
Get.log('"$newKey" onClose() called');
}
... ...
import 'dart:async';
/// Special callable class to keep the contract of a regular method, and avoid
/// overrides if you extend the class that uses it, as Dart has no final
/// methods.
... ... @@ -27,7 +25,7 @@ abstract class GetLifeCycle {
/// Called 1 frame after onInit(). It is the perfect place to enter
/// navigation events, like snackbar, dialogs, or a new route, or
/// async request.
void onReady() async {}
void onReady() {}
/// Called before [onDelete] method. [onClose] might be used to
/// dispose resources used by the controller. Like closing events,
... ... @@ -35,7 +33,7 @@ abstract class GetLifeCycle {
/// Or dispose objects that can potentially create some memory leaks,
/// like TextEditingControllers, AnimationControllers.
/// Might be useful as well to persist some data on disk.
FutureOr onClose() async {}
void onClose() {}
}
/// Allow track difference between GetxServices and GetxControllers
... ...
name: get_instance
description: A smart dependency injector to GetX™ framework.
version: 3.10.2
version: 3.12.0
homepage: https://github.com/jonataslaw/getx
environment:
... ...
## [3.12.0]
* Bump to Get 3.12.0
* Fix defaultCustomTransition
## [3.10.2]
- initial release
\ No newline at end of file
- initial release
... ...
... ... @@ -753,6 +753,10 @@ extension GetNavigation on GetInterface {
}
}
Future<T> showSnackbar<T>(GetBar snackbar) {
return key.currentState.push(SnackRoute<T>(snack: snackbar));
}
void snackbar(
String title,
String message, {
... ... @@ -802,7 +806,7 @@ extension GetNavigation on GetInterface {
Text(
title,
style: TextStyle(
color: colorText ?? Colors.black,
color: colorText ?? theme.iconTheme.color,
fontWeight: FontWeight.w800,
fontSize: 16,
),
... ... @@ -811,7 +815,7 @@ extension GetNavigation on GetInterface {
Text(
message,
style: TextStyle(
color: colorText ?? Colors.black,
color: colorText ?? theme.iconTheme.color,
fontWeight: FontWeight.w300,
fontSize: 14,
),
... ... @@ -912,14 +916,16 @@ extension GetNavigation on GetInterface {
}
void forceAppUpdate() {
void rebuild(Element el) {
el.markNeedsBuild();
el.visitChildren(rebuild);
void restart(Element element) {
element.markNeedsBuild();
element.visitChildren(restart);
}
(context as Element).visitChildren(rebuild);
restart(Get.context as Element);
}
void appUpdate() => getxController.update();
void changeTheme(ThemeData theme) {
getxController.setTheme(theme);
}
... ... @@ -1025,8 +1031,9 @@ Since version 2.8 it is possible to access the properties
bool get defaultOpaqueRoute => getxController.defaultOpaqueRoute;
Transition get defaultTransition => getxController.defaultTransition;
Duration get defaultTransitionDuration {
return getxController.defaultDialogTransitionDuration;
return getxController.defaultTransitionDuration;
}
Curve get defaultTransitionCurve => getxController.defaultTransitionCurve;
... ...
... ... @@ -15,11 +15,12 @@ class GetMaterialController extends GetxController {
bool defaultOpaqueRoute = true;
Transition defaultTransition;
Duration defaultTransitionDuration = Duration(milliseconds: 400);
Duration defaultTransitionDuration = Duration(milliseconds: 300);
Curve defaultTransitionCurve = Curves.easeOutQuad;
Curve defaultDialogTransitionCurve = Curves.easeOutQuad;
Duration defaultDialogTransitionDuration = Duration(milliseconds: 400);
Duration defaultDialogTransitionDuration = Duration(milliseconds: 300);
final routing = Routing();
... ...
... ... @@ -132,7 +132,7 @@ class GetMaterialApp extends StatelessWidget {
binding: unknownRoute.binding,
bindings: unknownRoute.bindings,
transitionDuration:
(transitionDuration ?? unknownRoute.transitionDuration),
(unknownRoute.transitionDuration ?? Get.defaultTransitionDuration),
transition: unknownRoute.transition,
popGesture: unknownRoute.popGesture,
fullscreenDialog: unknownRoute.fullscreenDialog,
... ... @@ -150,7 +150,7 @@ class GetMaterialApp extends StatelessWidget {
binding: match.route.binding,
bindings: match.route.bindings,
transitionDuration:
(transitionDuration ?? match.route.transitionDuration),
(match.route.transitionDuration ?? Get.defaultTransitionDuration),
transition: match.route.transition,
popGesture: match.route.popGesture,
fullscreenDialog: match.route.fullscreenDialog,
... ... @@ -171,7 +171,7 @@ class GetMaterialApp extends StatelessWidget {
binding: match.route.binding,
bindings: match.route.bindings,
transitionDuration:
(transitionDuration ?? match.route.transitionDuration),
(match.route.transitionDuration ?? Get.defaultTransitionDuration),
transition: match.route.transition,
popGesture: match.route.popGesture,
fullscreenDialog: match.route.fullscreenDialog,
... ...
... ... @@ -14,7 +14,7 @@ import 'transitions_type.dart';
class GetPageRoute<T> extends PageRoute<T> {
GetPageRoute({
RouteSettings settings,
this.transitionDuration = const Duration(milliseconds: 400),
this.transitionDuration = const Duration(milliseconds: 300),
this.opaque = true,
this.parameter,
this.curve,
... ...
... ... @@ -31,7 +31,7 @@ class GetPage {
this.alignment,
this.parameter,
this.opaque = true,
this.transitionDuration = const Duration(milliseconds: 400),
this.transitionDuration,
this.popGesture,
this.binding,
this.bindings,
... ...
... ... @@ -195,15 +195,10 @@ class GetBar<T extends Object> extends StatefulWidget {
/// Every other widget is ignored if this is not null.
final Form userInputForm;
SnackRoute<T> _snackRoute;
/// Show the snack. Kicks in [SnackbarStatus.OPENING] state
/// followed by [SnackbarStatus.OPEN]
Future<T> show() async {
_snackRoute = showSnack<T>(
snack: this,
) as SnackRoute<T>;
return await Get.key.currentState.push(_snackRoute);
Future<T> show<T>() async {
return Get.key.currentState.push(SnackRoute<T>(snack: this));
}
@override
... ...
... ... @@ -43,7 +43,6 @@ class SnackRoute<T> extends OverlayRoute<T> {
GetBar snack;
Builder _builder;
Future<T> get completed => _transitionCompleter.future;
final Completer<T> _transitionCompleter = Completer<T>();
SnackbarStatusCallback _snackbarStatus;
... ... @@ -164,14 +163,11 @@ class SnackRoute<T> extends OverlayRoute<T> {
/// The animation that drives the route's transition and the previous route's
/// forward transition.
Animation<Alignment> get animation => _animation;
Animation<Alignment> _animation;
/// The animation controller that the route uses to drive the transitions.
///
/// The animation itself is exposed by the [animation] property.
@protected
AnimationController get controller => _controller;
AnimationController _controller;
/// Called to create the animation controller that will drive the transitions
... ... @@ -235,7 +231,6 @@ class SnackRoute<T> extends OverlayRoute<T> {
T _result;
SnackbarStatus currentStatus;
//copy of `routes.dart`
void _handleStatusChanged(AnimationStatus status) {
switch (status) {
case AnimationStatus.completed:
... ... @@ -396,16 +391,4 @@ class SnackRoute<T> extends OverlayRoute<T> {
/// A short description of this route useful for debugging.
String get debugLabel => '$runtimeType';
@override
String toString() => '$runtimeType(animation: $_controller)';
}
SnackRoute showSnack<T>({@required GetBar snack}) {
assert(snack != null);
return SnackRoute<T>(
snack: snack,
settings: RouteSettings(name: "snackbar"),
);
}
... ...
name: get_navigation
description: Open Screens, bottomsheets, dialogs, e snackbars with no context using GetX™ framework.
version: 3.10.2
version: 3.12.0
homepage: https://github.com/jonataslaw/getx
environment:
... ...
## [3.12.0]
* Bump to Get 3.12.0
## [3.10.2]
- Initial release
... ...
import 'dart:async';
import 'dart:collection';
import 'package:meta/meta.dart';
import '../rx_core/rx_interface.dart';
part 'rx_num.dart';
... ... @@ -9,7 +11,10 @@ part 'rx_num.dart';
RxInterface getObs;
/// Base Rx class that manages all the stream logic for any Type.
class _RxImpl<T> implements RxInterface<T> {
abstract class _RxImpl<T> implements RxInterface<T> {
_RxImpl(T initial) {
_value = initial;
}
StreamController<T> subject = StreamController<T>.broadcast();
final _subscriptions = HashMap<Stream<T>, StreamSubscription>();
... ... @@ -181,9 +186,7 @@ class _RxImpl<T> implements RxInterface<T> {
/// Rx class for `bool` Type.
class RxBool extends _RxImpl<bool> {
RxBool([bool initial]) {
_value = initial;
}
RxBool([bool initial]) : super(initial);
bool operator &(bool other) => other && value;
... ... @@ -208,9 +211,7 @@ class RxBool extends _RxImpl<bool> {
/// Rx class for `String` Type.
class RxString extends _RxImpl<String> {
RxString([String initial]) {
_value = initial;
}
RxString([String initial]) : super(initial);
String operator +(String val) => _value + val;
}
... ... @@ -220,9 +221,7 @@ class RxString extends _RxImpl<String> {
/// For example, any custom "Model" class, like User().obs will use `Rx` as
/// wrapper.
class Rx<T> extends _RxImpl<T> {
Rx([T initial]) {
_value = initial;
}
Rx([T initial]) : super(initial);
// TODO: Look for a way to throw the Exception with proper details when the
// value [T] doesn't implement toJson().
... ... @@ -230,6 +229,81 @@ class Rx<T> extends _RxImpl<T> {
dynamic toJson() => (value as dynamic)?.toJson();
}
enum RxStatus { loading, error, success }
/// It's Experimental class, the Api can be change
abstract class RxState<T> extends _RxImpl<T> {
RxState(T initial) : super(initial) {
_fillEmptyStatus();
}
RxStatus _status;
bool get isNullOrEmpty {
if (_value == null) return true;
dynamic val = _value;
var result = false;
if (val is Iterable) {
result = val.isEmpty;
} else if (val is String) {
result = val.isEmpty;
} else if (val is Map) {
result = val.isEmpty;
}
return result;
}
void _fillEmptyStatus() {
_status = isNullOrEmpty ? RxStatus.loading : RxStatus.success;
}
RxStatus get status {
return _status;
}
bool get isLoading => _status == RxStatus.loading;
bool get hasError => _status == RxStatus.error;
bool get hasData => _status == RxStatus.success;
@protected
void refresh() {
subject.add(_value);
}
@protected
void update(void fn(T val)) {
fn(_value);
subject.add(_value);
}
@protected
T call([T v]) {
if (v != null) value = v;
return value;
}
@protected
set value(T val) {
if (_value == val && !firstRebuild) return;
firstRebuild = false;
_value = val;
subject.add(_value);
}
@protected
void change(T newState, {RxStatus status}) {
if (status != null) {
_status = status;
}
if (newState != _value) {
value = newState;
}
}
@override
dynamic toJson() => (value as dynamic)?.toJson();
}
extension StringExtension on String {
/// Returns a `RxString` with [this] `String` as initial value.
RxString get obs => RxString(this);
... ...
part of 'rx_impl.dart';
/// Base Rx class for all num Rx's.
class _BaseRxNum<T extends num> extends _RxImpl<T> {
abstract class _BaseRxNum<T extends num> extends _RxImpl<T> {
_BaseRxNum(T initial) : super(initial);
/// Addition operator. */
/// Multiplication operator.
... ... @@ -267,6 +269,8 @@ class _BaseRxNum<T extends num> extends _RxImpl<T> {
}
class RxNum extends _BaseRxNum<num> {
RxNum(num initial) : super(initial);
num operator +(num other) {
value += other;
return value;
... ... @@ -280,9 +284,7 @@ class RxNum extends _BaseRxNum<num> {
}
class RxDouble extends _BaseRxNum<double> {
RxDouble([double initial]) {
value = initial;
}
RxDouble([double initial]) : super(initial);
/// Addition operator.
RxDouble operator +(num other) {
... ... @@ -392,9 +394,7 @@ class RxDouble extends _BaseRxNum<double> {
}
class RxInt extends _BaseRxNum<int> {
RxInt([int initial]) {
value = initial;
}
RxInt([int initial]) : super(initial);
/// Addition operator.
RxInt operator +(int other) {
... ...
name: get_rx
description: A set of powerful tools to provide reactive programming for the GetX™ framework.
version: 3.10.2
version: 3.12.0
homepage: https://github.com/jonataslaw/getx
environment:
... ... @@ -24,4 +24,4 @@ dependencies:
dev_dependencies:
test: ">=1.0.0 <2.0.0"
test_coverage: ">=0.4.3 <1.0.0"
\ No newline at end of file
... ...
## [3.12.0]
* Bump to Get 3.12.0
## [3.10.2]
- initial release
... ...
import 'dart:async';
import 'package:flutter/scheduler.dart';
import 'package:get_instance/get_instance.dart';
... ... @@ -37,7 +35,7 @@ abstract class DisposableInterface extends GetLifeCycle {
/// navigation events, like snackbar, dialogs, or a new route, or
/// async request.
@override
void onReady() async {}
void onReady() {}
/// Called before [onDelete] method. [onClose] might be used to
/// dispose resources used by the controller. Like closing events,
... ... @@ -46,5 +44,5 @@ abstract class DisposableInterface extends GetLifeCycle {
/// like TextEditingControllers, AnimationControllers.
/// Might be useful as well to persist some data on disk.
@override
FutureOr onClose() async {}
void onClose() {}
}
... ...
... ... @@ -6,8 +6,11 @@ import 'package:get_instance/get_instance.dart';
import 'package:get_rx/get_rx.dart';
import '../../get_state_manager.dart';
typedef GetXControllerBuilder<T extends DisposableInterface> = Widget Function(
T controller);
class GetX<T extends DisposableInterface> extends StatefulWidget {
final Widget Function(T) builder;
final GetXControllerBuilder<T> builder;
final bool global;
// final Stream Function(T) stream;
... ...
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:get_core/get_core.dart';
import 'package:get_instance/get_instance.dart';
... ... @@ -23,16 +22,14 @@ typedef GetStateUpdate = void Function();
/// Avoids the potential (but extremely unlikely) issue of having
/// the Widget in a dispose() state, and abstracts the
/// API from the ugly fn((){}).
// TODO: check performance HIT for the extra method call.
mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> {
// To avoid the creation of an anonym function to be GC later.
// ignore: prefer_function_declarations_over_variables
static final VoidCallback _stateCallback = () {};
/// Experimental method to replace setState((){});
/// Used with GetStateUpdate.
void getUpdate() {
if (mounted) setState(_stateCallback);
if (mounted) setState(() {});
}
}
... ... @@ -123,8 +120,11 @@ class GetxController extends DisposableInterface {
/// }
}
typedef GetControllerBuilder<T extends DisposableInterface> = Widget Function(
T controller);
class GetBuilder<T extends GetxController> extends StatefulWidget {
final Widget Function(T) builder;
final GetControllerBuilder<T> builder;
final bool global;
final String id;
final String tag;
... ... @@ -189,9 +189,10 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>>
controller?.onStart();
}
if (widget.global && Get.smartManagement == SmartManagement.onlyBuilder) {
controller?.onStart();
}
// if (widget.global && Get.smartManagement ==
//SmartManagement.onlyBuilder) {
// controller?.onStart();
// }
_subscribeToController();
}
... ... @@ -269,3 +270,36 @@ class Value<T> extends GetxController {
update();
}
}
/// It's Experimental class, the Api can be change
abstract class GetState<T> extends GetxController {
GetState(T initialValue) {
_state = initialValue;
}
// StreamController<T> _subject;
// @override
// void onClose() {
// _subject?.close();
// }
// Stream<T> get stream {
// if (_subject == null) {
// _subject = StreamController<T>.broadcast();
// }
// return _subject.stream;
// }
T _state;
T get state => _state;
@protected
void change(T newState) {
if (newState != _state) {
_state = newState;
update();
}
}
}
... ...
import 'package:flutter/widgets.dart';
import 'package:get_instance/get_instance.dart';
import '../rx_flutter/rx_disposable.dart';
/// GetView is a great way of quickly access your Controller
/// without having to call Get.find<AwesomeController>() yourself.
... ... @@ -38,7 +39,8 @@ abstract class GetView<T> extends StatelessWidget {
Widget build(BuildContext context);
}
abstract class GetWidget<T extends GetLifeCycle> extends GetStatelessWidget {
abstract class GetWidget<T extends DisposableInterface>
extends GetStatelessWidget {
GetWidget({Key key}) : super(key: key);
final Set<T> _value = <T>{};
... ... @@ -91,18 +93,23 @@ class GetStatelessElement extends ComponentElement {
@override
void mount(Element parent, dynamic newSlot) {
widget.controller?.onStart();
if (widget?.controller?.initialized != null &&
!widget.controller.initialized) {
widget?.controller?.onStart();
}
super.mount(parent, newSlot);
}
@override
void unmount() {
widget.controller?.onClose();
widget?.controller?.onClose();
super.unmount();
}
}
abstract class GetStatelessWidget<T extends GetLifeCycle> extends Widget {
abstract class GetStatelessWidget<T extends DisposableInterface>
extends Widget {
const GetStatelessWidget({Key key}) : super(key: key);
@override
GetStatelessElement createElement() => GetStatelessElement(this);
... ...
name: get_state_manager
description: The most powerful, easier and flexible StateManager to Flutter and GetX™ framework.
version: 3.10.2
version: 3.12.0
homepage: https://github.com/jonataslaw/getx
environment:
... ...
## [3.12.3]
* Added compatibility with last GetX
## [3.12.0]
* Bump to Get 3.12.0
## [3.11.0]
- Compatibility with get 3.11.0
... ...
... ... @@ -23,10 +23,11 @@ environment:
dependencies:
flutter:
sdk: flutter
get_test:
path: ../
get:
path: ../../../getx
git:
url: git://github.com/jonataslaw/getx.git
path: getx
ref: master
# The following adds the Cupertino Icons font to your application.
... ...
... ... @@ -3,7 +3,9 @@ import 'package:flutter/scheduler.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get_navigation/get_navigation.dart';
import 'package:get_state_manager/get_state_manager.dart';
import 'package:image_test_utils/image_test_utils.dart';
import 'package:meta/meta.dart';
import 'utils/image_test.dart'
if (dart.library.io) 'utils/image_test_utils.dart';
class _Wrapper extends StatelessWidget {
final Widget child;
... ... @@ -26,6 +28,7 @@ class _Wrapper extends StatelessWidget {
}
}
@isTest
void testController<T>(
String description,
void Function(T) callback, {
... ... @@ -44,6 +47,7 @@ void testController<T>(
});
}
@isTest
Future<T> testGetX<T extends DisposableInterface>(
String description, {
@required GetX<T> widget,
... ... @@ -60,6 +64,7 @@ Future<T> testGetX<T extends DisposableInterface>(
return controller;
}
@isTest
Future<T> testGetBuilder<T extends GetxController>(
String description, {
@required GetBuilder<T> widget,
... ... @@ -76,6 +81,7 @@ Future<T> testGetBuilder<T extends GetxController>(
return controller;
}
@isTest
Future<T> testObx<T extends GetxController>(
String description, {
@required T controller,
... ... @@ -91,6 +97,7 @@ Future<T> testObx<T extends GetxController>(
return controller;
}
@isTest
void getTest(
String description, {
@required WidgetTesterCallback widgetTest,
... ...
R provideMockedNetworkImages<R>(R body()) {
return body();
}
... ...
import 'dart:async';
import 'dart:io';
import 'package:mockito/mockito.dart';
/// Copyright 2018 Iiro Krankka
/// Redistribution and use in source and binary forms, with or without
/// modification, are permitted provided that the following conditions are met:
/// 1. Redistributions of source code must retain the above copyright notice,
/// this list of conditions and the following disclaimer.
/// 2. Redistributions in binary form must reproduce the above copyright
/// notice, this list of conditions and the following disclaimer in the
/// documentation and/or other materials provided with the distribution.
/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
/// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
/// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
/// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
/// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
/// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// Runs [body] in a fresh [Zone] that provides mocked responses for
/// [Image.network] widgets.
///
/// Behind the scenes, this creates a mocked HTTP client that responds
/// with mocked
/// image data to all HTTP GET requests.
///
/// This is a workaround needed for widget tests that use network images.
/// Without
/// the mocked HTTP client, any widget tests that pump a widget tree containing
/// [Image.network] widgets will crash.
///
/// By default, the mocked HTTP client will respond with [_transparentImage]. If
/// provided, it will use [imageBytes] instead.
///
/// Example usage in a test case:
///
/// ```
/// void main() {
/// testWidgets('should not crash', (WidgetTester tester) async {
/// provideMockedNetworkImages(() async {
/// await tester.pumpWidget(
/// MaterialApp(
/// home: Image.network('https://example.com/image.png'),
/// ),
/// );
/// });
/// });
/// }
/// ```
///
/// Note that you'll want to add this package to the dev_dependencies instead of
/// the regular dependencies block on your pubspec.yaml.
///
/// For more context about [Image.network] widgets failing in widget tests, see
/// these issues:
///
/// * https://github.com/flutter/flutter/issues/13433
/// * https://github.com/flutter/flutter_markdown/pull/17
///
/// The underlying code is taken from the Flutter repo:
/// https://github.com/flutter/flutter/blob/master/dev/manual_tests/test/mock_image_http.dart
R provideMockedNetworkImages<R>(R body(),
{List<int> imageBytes = _transparentImage}) {
return HttpOverrides.runZoned(
body,
createHttpClient: (_) => _createMockImageHttpClient(_, imageBytes),
);
}
class MockHttpClient extends Mock implements HttpClient {}
class MockHttpClientRequest extends Mock implements HttpClientRequest {}
class MockHttpClientResponse extends Mock implements HttpClientResponse {}
class MockHttpHeaders extends Mock implements HttpHeaders {}
// Returns a mock HTTP client that responds with an image to all requests.
MockHttpClient _createMockImageHttpClient(
SecurityContext _, List<int> imageBytes) {
final client = MockHttpClient();
final request = MockHttpClientRequest();
final response = MockHttpClientResponse();
final headers = MockHttpHeaders();
when(client.getUrl(any))
.thenAnswer((_) => Future<HttpClientRequest>.value(request));
when(request.headers).thenReturn(headers);
when(request.close())
.thenAnswer((_) => Future<HttpClientResponse>.value(response));
when(response.contentLength).thenReturn(_transparentImage.length);
when(response.statusCode).thenReturn(HttpStatus.ok);
when(response.listen(any)).thenAnswer((invocation) {
final onData =
invocation.positionalArguments[0] as void Function(List<int>);
final onDone = invocation.namedArguments[#onDone] as void Function();
final onError = invocation.namedArguments[#onError] as void Function(Object,
[StackTrace]);
final cancelOnError = invocation.namedArguments[#cancelOnError] as bool;
return Stream<List<int>>.fromIterable(<List<int>>[imageBytes]).listen(
onData,
onDone: onDone,
onError: onError,
cancelOnError: cancelOnError);
});
return client;
}
const List<int> _transparentImage = <int>[
0x89,
0x50,
0x4E,
0x47,
0x0D,
0x0A,
0x1A,
0x0A,
0x00,
0x00,
0x00,
0x0D,
0x49,
0x48,
0x44,
0x52,
0x00,
0x00,
0x00,
0x01,
0x00,
0x00,
0x00,
0x01,
0x08,
0x06,
0x00,
0x00,
0x00,
0x1F,
0x15,
0xC4,
0x89,
0x00,
0x00,
0x00,
0x0A,
0x49,
0x44,
0x41,
0x54,
0x78,
0x9C,
0x63,
0x00,
0x01,
0x00,
0x00,
0x05,
0x00,
0x01,
0x0D,
0x0A,
0x2D,
0xB4,
0x00,
0x00,
0x00,
0x00,
0x49,
0x45,
0x4E,
0x44,
0xAE,
];
... ...
name: get_test
description: A package that facilitates the creation of tests for applications built with GetX
version: 3.11.0
version: 3.12.3
homepage: https://github.com/jonataslaw/getx
environment:
... ... @@ -10,7 +10,7 @@ environment:
dependencies:
flutter:
sdk: flutter
mockito: ">=3.0.0 <4.0.0"
mockito: ">=3.0.0 <5.0.0"
get_navigation:
git:
url: git://github.com/jonataslaw/getx.git
... ... @@ -21,7 +21,7 @@ dependencies:
url: git://github.com/jonataslaw/getx.git
path: packages/get_state_manager
ref: master
image_test_utils: ">=1.0.0 <2.0.0"
meta: ">=1.1.0 <2.0.0"
flutter_test:
sdk: flutter
... ...
## [3.12.0]
* Bump to Get 3.12.0
* Improve capitalizeFirst method
## [3.10.2]
- Initial release
... ...
name: get_utils
description: A set of tools that allows you to access high-level APIs and obtain validation tools for Flutter and GetX™ framework.
version: 3.10.2
version: 3.12.0
homepage: https://github.com/jonataslaw/getx
environment:
... ...
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.2"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.3"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.13"
effective_dart:
dependency: "direct dev"
description:
name: effective_dart
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.4"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.8"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.8"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.5"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.17"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
sdks:
dart: ">=2.9.0-14.0.dev <3.0.0"