Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
fluttertpc_get
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Jonny Borges
2022-01-09 10:36:22 -0300
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
f213f4db62b67936eb583bc7a308fe14282eeb68
f213f4db
1 parent
70a34a63
improve code
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
293 additions
and
160 deletions
example/pubspec.yaml
example/test/widget_test.dart
example_nav2/lib/app/modules/splash/controllers/splash_service.dart
example_nav2/lib/main.dart
lib/get_instance/src/lifecycle.dart
lib/get_navigation/src/nav2/get_router_delegate.dart
lib/get_navigation/src/routes/default_route.dart
lib/get_navigation/src/routes/route_report.dart
lib/get_rx/src/rx_types/rx_core/rx_impl.dart
lib/get_rx/src/rx_types/rx_core/rx_interface.dart
lib/get_state_manager/get_state_manager.dart
lib/get_state_manager/src/rx_flutter/rx_disposable.dart
lib/get_state_manager/src/rx_flutter/rx_getx_widget.dart
lib/get_state_manager/src/rx_flutter/rx_notifier.dart
lib/get_state_manager/src/simple/get_controllers.dart
lib/get_state_manager/src/simple/get_state.dart
lib/get_state_manager/src/simple/list_notifier.dart
lib/get_state_manager/src/simple/mixin_state.dart → lib/get_state_manager/src/simple/mixin_builder.dart
lib/get_state_manager/src/simple/simple_builder.dart
lib/get_utils/src/extensions/context_extensions.dart
lib/get_utils/src/extensions/dynamic_extensions.dart
lib/get_utils/src/extensions/string_extensions.dart
lib/get_utils/src/widgets/otimized_listview.dart
test/state_manager/get_mixin_state_test.dart
example/pubspec.yaml
View file @
f213f4d
...
...
@@ -20,6 +20,10 @@ version: 1.0.0+1
environment
:
sdk
:
"
>=2.12.0
<3.0.0"
dependency_overrides
:
get
:
path
:
../
dependencies
:
flutter
:
sdk
:
flutter
...
...
@@ -33,6 +37,7 @@ dependencies:
dev_dependencies
:
flutter_test
:
sdk
:
flutter
get_test
:
4.0.1
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
...
...
example/test/widget_test.dart
deleted
100644 → 0
View file @
70a34a6
example_nav2/lib/app/modules/splash/controllers/splash_service.dart
View file @
f213f4d
import
'dart:async'
;
import
'package:get/get.dart'
;
import
'package:async/async.dart'
;
import
'package:get/get.dart'
;
class
SplashService
extends
GetxService
{
final
welcomeStr
=
[
'GetX'
,
'Rules!'
];
...
...
example_nav2/lib/main.dart
View file @
f213f4d
import
'package:example_nav2/app/modules/splash/controllers/splash_service.dart'
;
import
'package:example_nav2/app/modules/splash/views/splash_view.dart'
;
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'app/modules/splash/controllers/splash_service.dart'
;
import
'app/modules/splash/views/splash_view.dart'
;
import
'app/routes/app_pages.dart'
;
import
'services/auth_service.dart'
;
...
...
lib/get_instance/src/lifecycle.dart
View file @
f213f4d
...
...
@@ -76,3 +76,11 @@ mixin GetLifeCycleMixin {
/// Allow track difference between GetxServices and GetxControllers
mixin
GetxServiceMixin
{}
/// Unlike GetxController, which serves to control events on each of its pages,
/// GetxService is not automatically disposed (nor can be removed with
/// Get.delete()).
/// It is ideal for situations where, once started, that service will
/// remain in memory, such as Auth control for example. Only way to remove
/// it is Get.reset().
abstract
class
GetxService
with
GetLifeCycleMixin
,
GetxServiceMixin
{}
...
...
lib/get_navigation/src/nav2/get_router_delegate.dart
View file @
f213f4d
...
...
@@ -2,9 +2,9 @@ import 'dart:async';
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'../../../get.dart'
;
import
'../../../get_state_manager/src/simple/list_notifier.dart'
;
import
'get_navigator.dart'
;
/// Enables the user to customize the intended pop behavior
///
...
...
lib/get_navigation/src/routes/default_route.dart
View file @
f213f4d
...
...
@@ -4,6 +4,21 @@ import '../../../get.dart';
import
'../router_report.dart'
;
import
'get_transition_mixin.dart'
;
@optionalTypeArgs
mixin
RouteReportMixin
<
T
extends
StatefulWidget
>
on
State
<
T
>
{
@override
void
initState
()
{
super
.
initState
();
RouterReportManager
.
instance
.
reportCurrentRoute
(
this
);
}
@override
void
dispose
()
{
super
.
dispose
();
RouterReportManager
.
instance
.
reportRouteDispose
(
this
);
}
}
mixin
PageRouteReportMixin
<
T
>
on
Route
<
T
>
{
@override
void
install
()
{
...
...
lib/get_navigation/src/routes/route_report.dart
0 → 100644
View file @
f213f4d
import
'package:flutter/material.dart'
;
import
'../router_report.dart'
;
import
'default_route.dart'
;
class
RouteReport
extends
StatefulWidget
{
RouteReport
({
Key
?
key
,
required
this
.
builder
})
:
super
(
key:
key
);
final
WidgetBuilder
builder
;
@override
_RouteReportState
createState
()
=>
_RouteReportState
();
}
class
_RouteReportState
extends
State
<
RouteReport
>
with
RouteReportMixin
{
@override
void
initState
()
{
RouterReportManager
.
instance
.
reportCurrentRoute
(
this
);
super
.
initState
();
}
@override
void
dispose
()
{
RouterReportManager
.
instance
.
reportRouteDispose
(
this
);
super
.
dispose
();
}
@override
Widget
build
(
BuildContext
context
)
{
return
widget
.
builder
(
context
);
}
}
...
...
lib/get_rx/src/rx_types/rx_core/rx_impl.dart
View file @
f213f4d
...
...
@@ -102,9 +102,7 @@ mixin RxObjectMixin<T> on GetListenable<T> {
sentToStream
=
false
;
if
(
value
==
val
&&
!
firstRebuild
)
return
;
firstRebuild
=
false
;
// _value = val;
sentToStream
=
true
;
//TODO: Check this
super
.
value
=
val
;
}
...
...
@@ -121,7 +119,6 @@ mixin RxObjectMixin<T> on GetListenable<T> {
cancelOnError:
cancelOnError
,
);
//TODO: Change to refresh????
subject
.
add
(
value
);
return
subscription
;
...
...
@@ -140,53 +137,6 @@ mixin RxObjectMixin<T> on GetListenable<T> {
}
}
//class RxNotifier<T> = RxInterface<T> with NotifyManager<T>;
// mixin NotifyManager<T> {
// GetStream<T> subject = GetStream<T>();
// final _subscriptions = <GetStream, List<StreamSubscription>>{};
// bool get canUpdate => _subscriptions.isNotEmpty;
// /// This is an internal method.
// /// Subscribe to changes on the inner stream.
// void addListener(GetStream<T> rxGetx) {
// if (!_subscriptions.containsKey(rxGetx)) {
// final subs = rxGetx.listen((data) {
// if (!subject.isClosed) subject.add(data);
// });
// final listSubscriptions =
// _subscriptions[rxGetx] ??= <StreamSubscription>[];
// listSubscriptions.add(subs);
// }
// }
// StreamSubscription<T> listen(
// void Function(T) onData, {
// Function? onError,
// void Function()? onDone,
// bool? cancelOnError,
// }) =>
// subject.listen(
// onData,
// onError: onError,
// onDone: onDone,
// cancelOnError: cancelOnError ?? false,
// );
// /// Closes the subscriptions for this Rx, releasing the resources.
// void close() {
// _subscriptions.forEach((getStream, _subscriptions) {
// for (final subscription in _subscriptions) {
// subscription.cancel();
// }
// });
// _subscriptions.clear();
// subject.close();
// }
// }
/// Base Rx class that manages all the stream logic for any Type.
abstract
class
_RxImpl
<
T
>
extends
GetListenable
<
T
>
with
RxObjectMixin
<
T
>
{
_RxImpl
(
T
initial
)
:
super
(
initial
);
...
...
lib/get_rx/src/rx_types/rx_core/rx_interface.dart
View file @
f213f4d
...
...
@@ -2,33 +2,15 @@ part of rx_types;
/// This class is the foundation for all reactive (Rx) classes that makes Get
/// so powerful.
/// This interface is the contract that _RxImpl]<T> uses in all it's
/// This interface is the contract that
[
_RxImpl]<T> uses in all it's
/// subclass.
abstract
class
RxInterface
<
T
>
{
//bool get canUpdate;
/// Adds a listener to stream
void
addListener
(
VoidCallback
listener
);
abstract
class
RxInterface
<
T
>
implements
ValueListenable
<
T
>
{
/// Close the Rx Variable
void
close
();
/// Calls `callback` with current value, when the value changes.
StreamSubscription
<
T
>
listen
(
void
Function
(
T
event
)
onData
,
{
Function
?
onError
,
void
Function
()?
onDone
,
bool
?
cancelOnError
});
/// Avoids an unsafe usage of the `proxy`
// static T notifyChildren<T>(RxNotifier observer, ValueGetter<T> builder) {
// final _observer = RxInterface.proxy;
// RxInterface.proxy = observer;
// final result = builder();
// if (!observer.canUpdate) {
// RxInterface.proxy = _observer;
// throw ObxError();
// }
// RxInterface.proxy = _observer;
// return result;
// }
}
class
ObxError
{
...
...
lib/get_state_manager/get_state_manager.dart
View file @
f213f4d
library
get_state_manager
;
export
'src/rx_flutter/rx_disposable.dart'
;
export
'src/rx_flutter/rx_getx_widget.dart'
;
export
'src/rx_flutter/rx_notifier.dart'
;
export
'src/rx_flutter/rx_obx_widget.dart'
;
...
...
@@ -9,5 +8,4 @@ export 'src/simple/get_controllers.dart';
export
'src/simple/get_responsive.dart'
;
export
'src/simple/get_state.dart'
;
export
'src/simple/get_view.dart'
;
export
'src/simple/mixin_state.dart'
;
export
'src/simple/simple_builder.dart'
;
...
...
lib/get_state_manager/src/rx_flutter/rx_disposable.dart
deleted
100644 → 0
View file @
70a34a6
import
'../../../get_instance/src/lifecycle.dart'
;
/// Unlike GetxController, which serves to control events on each of its pages,
/// GetxService is not automatically disposed (nor can be removed with
/// Get.delete()).
/// It is ideal for situations where, once started, that service will
/// remain in memory, such as Auth control for example. Only way to remove
/// it is Get.reset().
abstract
class
GetxService
with
GetLifeCycleMixin
,
GetxServiceMixin
{}
// abstract class DisposableInterface with GetLifeCycleMixin {}
lib/get_state_manager/src/rx_flutter/rx_getx_widget.dart
View file @
f213f4d
...
...
@@ -113,20 +113,25 @@ class GetXState<T extends GetLifeCycleMixin> extends State<GetX<T>> {
disposer
();
}
disposers
.
clear
();
controller
=
null
;
_isCreator
=
null
;
super
.
dispose
();
}
void
_update
()
{
if
(
mounted
)
{
setState
(()
{});
}
}
final
disposers
=
<
Disposer
>[];
@override
Widget
build
(
BuildContext
context
)
=>
NotifierManager
.
instance
.
exchange
(
disposers
,
_update
,
()
=>
widget
.
builder
(
controller
!));
Widget
build
(
BuildContext
context
)
=>
Notifier
.
instance
.
append
(
NotifyData
(
disposers:
disposers
,
updater:
_update
),
()
=>
widget
.
builder
(
controller
!));
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
...
...
lib/get_state_manager/src/rx_flutter/rx_notifier.dart
View file @
f213f4d
...
...
@@ -3,6 +3,7 @@ import 'dart:async';
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'../../../get_rx/src/rx_types/rx_types.dart'
;
import
'../../../instance_manager.dart'
;
import
'../../get_state_manager.dart'
;
import
'../simple/list_notifier.dart'
;
...
...
@@ -78,8 +79,7 @@ mixin StateMixin<T> on ListNotifier {
}
}
class
GetListenable
<
T
>
extends
ListNotifierSingle
implements
ValueListenable
<
T
>
{
class
GetListenable
<
T
>
extends
ListNotifierSingle
implements
RxInterface
<
T
>
{
GetListenable
(
T
val
)
:
_value
=
val
;
StreamController
<
T
>?
_controller
;
...
...
@@ -96,6 +96,7 @@ class GetListenable<T> extends ListNotifierSingle
_controller
?.
add
(
_value
);
}
@override
@mustCallSuper
void
close
()
{
removeListener
(
_streamListener
);
...
...
@@ -132,6 +133,7 @@ class GetListenable<T> extends ListNotifierSingle
return
value
;
}
@override
StreamSubscription
<
T
>
listen
(
void
Function
(
T
)?
onData
,
{
Function
?
onError
,
...
...
@@ -188,6 +190,8 @@ class Value<T> extends ListNotifier
dynamic
toJson
()
=>
(
value
as
dynamic
)?.
toJson
();
}
/// GetNotifier has a native status and state implementation, with the
/// Get Lifecycle
abstract
class
GetNotifier
<
T
>
extends
Value
<
T
>
with
GetLifeCycleMixin
{
GetNotifier
(
T
initial
)
:
super
(
initial
);
}
...
...
@@ -198,6 +202,7 @@ extension StateExt<T> on StateMixin<T> {
Widget
Function
(
String
?
error
)?
onError
,
Widget
?
onLoading
,
Widget
?
onEmpty
,
WidgetBuilder
?
onCustom
,
})
{
return
Observer
(
builder:
(
_
)
{
if
(
status
.
isLoading
)
{
...
...
@@ -210,6 +215,11 @@ extension StateExt<T> on StateMixin<T> {
return
onEmpty
!=
null
?
onEmpty
:
SizedBox
.
shrink
();
// Also can be widget(null); but is risky
}
else
if
(
status
.
isSuccess
)
{
return
widget
(
value
);
}
else
if
(
status
.
isCustom
)
{
return
onCustom
?.
call
(
_
)
??
SizedBox
.
shrink
();
// Also can be widget(null); but is risky
}
return
widget
(
value
);
});
...
...
@@ -246,6 +256,7 @@ extension StatusDataExt<T> on GetState<T> {
bool
get
isSuccess
=>
this
is
SuccessState
;
bool
get
isError
=>
this
is
ErrorState
;
bool
get
isEmpty
=>
this
is
EmptyState
;
bool
get
isCustom
=>
!
isLoading
&&
!
isSuccess
&&
!
isError
&&
!
isEmpty
;
String
get
errorMessage
{
final
isError
=
this
is
ErrorState
;
if
(
isError
)
{
...
...
lib/get_state_manager/src/simple/get_controllers.dart
View file @
f213f4d
...
...
@@ -26,6 +26,8 @@ abstract class GetxController extends ListNotifier with GetLifeCycleMixin {
}
}
/// this mixin allow to fetch data when the scroll is at the bottom or on the
/// top
mixin
ScrollMixin
on
GetLifeCycleMixin
{
final
ScrollController
scroll
=
ScrollController
();
...
...
@@ -59,8 +61,10 @@ mixin ScrollMixin on GetLifeCycleMixin {
}
}
/// this method is called when the scroll is at the bottom
Future
<
void
>
onEndScroll
();
/// this method is called when the scroll is at the top
Future
<
void
>
onTopScroll
();
@override
...
...
@@ -70,13 +74,17 @@ mixin ScrollMixin on GetLifeCycleMixin {
}
}
/// A clean controller to be used with only Rx variables
abstract
class
RxController
with
GetLifeCycleMixin
{}
/// A recommended way to use Getx with Future fetching
abstract
class
StateController
<
T
>
extends
GetxController
with
StateMixin
<
T
>
{}
/// A controller with super lifecycles (including native lifecycles) and StateMixins
abstract
class
SuperController
<
T
>
extends
FullLifeCycleController
with
FullLifeCycleMixin
,
StateMixin
<
T
>
{}
/// A controller with super lifecycles (including native lifecycles)
abstract
class
FullLifeCycleController
extends
GetxController
with
// ignore: prefer_mixin
...
...
@@ -116,8 +124,8 @@ mixin FullLifeCycleMixin on FullLifeCycleController {
}
}
void
onResumed
();
void
onPaused
();
void
onInactive
();
void
onDetached
();
void
onResumed
()
{}
void
onPaused
()
{}
void
onInactive
()
{}
void
onDetached
()
{}
}
...
...
lib/get_state_manager/src/simple/get_state.dart
View file @
f213f4d
...
...
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import
'../../../instance_manager.dart'
;
import
'../../get_state_manager.dart'
;
import
'list_notifier.dart'
;
typedef
InitBuilder
<
T
>
=
T
Function
();
...
...
@@ -37,7 +38,7 @@ class GetBuilder<T extends GetxController> extends StatelessWidget {
final
void
Function
(
BindElement
<
T
>
state
)?
initState
,
dispose
,
didChangeDependencies
;
final
void
Function
(
Bind
Wrapp
er
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
final
void
Function
(
Binder
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
didUpdateWidget
;
final
T
?
init
;
...
...
@@ -59,7 +60,7 @@ class GetBuilder<T extends GetxController> extends StatelessWidget {
@override
Widget
build
(
BuildContext
context
)
{
return
Bind
Wrapp
er
(
return
Binder
(
init:
init
==
null
?
null
:
()
=>
init
!,
global:
global
,
autoRemove:
autoRemove
,
...
...
@@ -108,7 +109,7 @@ abstract class Bind<T> extends StatelessWidget {
final
void
Function
(
BindElement
<
T
>
state
)?
initState
,
dispose
,
didChangeDependencies
;
final
void
Function
(
Bind
Wrapp
er
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
final
void
Function
(
Binder
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
didUpdateWidget
;
final
Widget
?
child
;
...
...
@@ -193,8 +194,7 @@ abstract class Bind<T> extends StatelessWidget {
void
Function
(
BindElement
<
T
>
state
)?
initState
,
void
Function
(
BindElement
<
T
>
state
)?
dispose
,
void
Function
(
BindElement
<
T
>
state
)?
didChangeDependencies
,
void
Function
(
BindWrapper
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
didUpdateWidget
,
void
Function
(
Binder
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
didUpdateWidget
,
})
=>
_FactoryBind
<
T
>(
// key: key,
...
...
@@ -218,7 +218,7 @@ abstract class Bind<T> extends StatelessWidget {
// Object Function(T value)? filter,
})
{
final
inheritedElement
=
context
.
getElementForInheritedWidgetOfExactType
<
Bind
Wrapp
er
<
T
>>()
context
.
getElementForInheritedWidgetOfExactType
<
Binder
<
T
>>()
as
BindElement
<
T
>?;
if
(
inheritedElement
==
null
)
{
...
...
@@ -265,7 +265,7 @@ class _FactoryBind<T> extends Bind<T> {
dispose
,
didChangeDependencies
;
@override
final
void
Function
(
Bind
Wrapp
er
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
final
void
Function
(
Binder
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
didUpdateWidget
;
@override
...
...
@@ -307,7 +307,7 @@ class _FactoryBind<T> extends Bind<T> {
@override
Widget
build
(
BuildContext
context
)
{
return
Bind
Wrapp
er
<
T
>(
return
Binder
<
T
>(
init:
init
,
global:
global
,
autoRemove:
autoRemove
,
...
...
@@ -340,12 +340,12 @@ class Binds extends StatelessWidget {
binds
.
reversed
.
fold
(
child
,
(
acc
,
e
)
=>
e
.
_copyWithChild
(
acc
));
}
class
Bind
Wrapp
er
<
T
>
extends
InheritedWidget
{
class
Binder
<
T
>
extends
InheritedWidget
{
/// Create an inherited widget that updates its dependents when [controller]
/// sends notifications.
///
/// The [child] argument is required
const
Bind
Wrapp
er
({
const
Binder
({
Key
?
key
,
required
Widget
child
,
this
.
init
,
...
...
@@ -371,11 +371,11 @@ class BindWrapper<T> extends InheritedWidget {
final
void
Function
(
BindElement
<
T
>
state
)?
initState
,
dispose
,
didChangeDependencies
;
final
void
Function
(
Bind
Wrapp
er
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
final
void
Function
(
Binder
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
didUpdateWidget
;
@override
bool
updateShouldNotify
(
Bind
Wrapp
er
<
T
>
oldWidget
)
{
bool
updateShouldNotify
(
Binder
<
T
>
oldWidget
)
{
return
oldWidget
.
id
!=
id
||
oldWidget
.
global
!=
global
||
oldWidget
.
autoRemove
!=
autoRemove
||
...
...
@@ -389,10 +389,12 @@ class BindWrapper<T> extends InheritedWidget {
/// The BindElement is responsible for injecting dependencies into the widget
/// tree so that they can be observed
class
BindElement
<
T
>
extends
InheritedElement
{
BindElement
(
Bind
Wrapp
er
<
T
>
widget
)
:
super
(
widget
)
{
BindElement
(
Binder
<
T
>
widget
)
:
super
(
widget
)
{
initState
();
}
final
disposers
=
<
Disposer
>[];
InitBuilder
<
T
>?
_controllerBuilder
;
T
?
_controller
;
...
...
@@ -486,6 +488,12 @@ class BindElement<T> extends InheritedElement {
}
}
for
(
final
disposer
in
disposers
)
{
disposer
();
}
disposers
.
clear
();
_remove
?.
call
();
_controller
=
null
;
_isCreator
=
null
;
...
...
@@ -497,12 +505,12 @@ class BindElement<T> extends InheritedElement {
}
@override
Bind
Wrapper
<
T
>
get
widget
=>
super
.
widget
as
BindWrapp
er
<
T
>;
Bind
er
<
T
>
get
widget
=>
super
.
widget
as
Bind
er
<
T
>;
var
_dirty
=
false
;
@override
void
update
(
Bind
Wrapp
er
<
T
>
newWidget
)
{
void
update
(
Binder
<
T
>
newWidget
)
{
final
oldNotifier
=
widget
.
id
;
final
newNotifier
=
newWidget
.
id
;
if
(
oldNotifier
!=
newNotifier
&&
_wasStarted
)
{
...
...
@@ -523,7 +531,11 @@ class BindElement<T> extends InheritedElement {
if
(
_dirty
)
{
notifyClients
(
widget
);
}
// return Notifier.instance.notifyAppend(
// NotifyData(
// disposers: disposers, updater: getUpdate, throwException: false),
return
super
.
build
();
//);
}
void
getUpdate
()
{
...
...
@@ -532,7 +544,7 @@ class BindElement<T> extends InheritedElement {
}
@override
void
notifyClients
(
Bind
Wrapp
er
<
T
>
oldWidget
)
{
void
notifyClients
(
Binder
<
T
>
oldWidget
)
{
super
.
notifyClients
(
oldWidget
);
_dirty
=
false
;
}
...
...
lib/get_state_manager/src/simple/list_notifier.dart
View file @
f213f4d
...
...
@@ -12,10 +12,14 @@ typedef GetStateUpdate = void Function();
class
ListNotifier
extends
Listenable
with
ListNotifierSingleMixin
,
ListNotifierGroupMixin
{}
/// A Notifier with single listeners
class
ListNotifierSingle
=
ListNotifier
with
ListNotifierSingleMixin
;
/// A notifier with group of listeners identified by id
class
ListNotifierGroup
=
ListNotifier
with
ListNotifierGroupMixin
;
/// This mixin add to Listenable the addListener, removerListener and
/// containsListener implementation
mixin
ListNotifierSingleMixin
on
Listenable
{
List
<
GetStateUpdate
?>?
_updaters
=
<
GetStateUpdate
?>[];
...
...
@@ -44,12 +48,12 @@ mixin ListNotifierSingleMixin on Listenable {
@protected
void
reportRead
()
{
Notifier
Manager
.
instance
.
notify
(
this
);
Notifier
.
instance
.
read
(
this
);
}
@protected
void
reportAdd
(
VoidCallback
disposer
)
{
Notifier
Manager
.
instance
.
reportA
dd
(
disposer
);
Notifier
.
instance
.
a
dd
(
disposer
);
}
void
_notifyUpdate
()
{
...
...
@@ -96,7 +100,7 @@ mixin ListNotifierGroupMixin on Listenable {
@protected
void notifyGroupChildrens(Object id) {
assert(_debugAssertNotDisposed());
Notifier
Manager.instance.notify
(_updatersGroupIds![id]!);
Notifier
.instance.read
(_updatersGroupIds![id]!);
}
bool containsId(Object id) {
...
...
@@ -148,44 +152,47 @@ mixin ListNotifierGroupMixin on Listenable {
}
}
class
NotifierManager
{
NotifierManager
.
_
();
class
Notifier
{
Notifier
.
_
();
static
NotifierManager
?
_instance
;
static
Notifier
?
_instance
;
static
Notifier
get
instance
=>
_instance
??=
Notifier
.
_
();
static
NotifierManager
get
instance
=>
_instance
??=
NotifierManager
.
_
()
;
NotifyData
?
_notifyData
;
GetStateUpdate
?
_setter
;
List
<
VoidCallback
>?
_remove
;
void
reportAdd
(
VoidCallback
listener
)
{
_remove
?.
add
(
listener
);
void
add
(
VoidCallback
listener
)
{
_notifyData
?.
disposers
.
add
(
listener
);
}
void
notify
(
ListNotifierSingleMixin
_updaters
)
{
final
listener
=
_setter
;
if
(
listener
!=
null
)
{
if
(!
_updaters
.
containsListener
(
listener
))
{
void
read
(
ListNotifierSingleMixin
_updaters
)
{
final
listener
=
_notifyData
?.
updater
;
if
(
listener
!=
null
&&
!
_updaters
.
containsListener
(
listener
))
{
_updaters
.
addListener
(
listener
);
reportAdd
(()
=>
_updaters
.
removeListener
(
listener
));
}
add
(()
=>
_updaters
.
removeListener
(
listener
));
}
}
T
exchange
<
T
>(
List
<
VoidCallback
>
disposers
,
GetStateUpdate
setState
,
T
Function
()
builder
)
{
_remove
=
disposers
;
_setter
=
setState
;
T
append
<
T
>(
NotifyData
data
,
T
Function
()
builder
)
{
_notifyData
=
data
;
final
result
=
builder
();
if
(
d
isposers
.
isEmpty
)
{
if
(
d
ata
.
disposers
.
isEmpty
&&
data
.
throwException
)
{
throw
ObxError
();
}
_remove
=
null
;
_setter
=
null
;
_notifyData
=
data
;
return
result
;
}
}
class
NotifyData
{
const
NotifyData
(
{
required
this
.
updater
,
required
this
.
disposers
,
this
.
throwException
=
true
});
final
GetStateUpdate
updater
;
final
List
<
VoidCallback
>
disposers
;
final
bool
throwException
;
}
class
ObxError
{
const
ObxError
();
@override
...
...
lib/get_state_manager/src/simple/mixin_
state
.dart → lib/get_state_manager/src/simple/mixin_
builder
.dart
View file @
f213f4d
import
'package:flutter/material.dart'
;
import
'../../get_state_manager.dart'
;
import
'../rx_flutter/rx_obx_widget.dart'
;
import
'get_controllers.dart'
;
import
'get_state.dart'
;
class
MixinBuilder
<
T
extends
GetxController
>
extends
StatelessWidget
{
@required
...
...
@@ -11,7 +13,7 @@ class MixinBuilder<T extends GetxController> extends StatelessWidget {
final
void
Function
(
BindElement
<
T
>
state
)?
initState
,
dispose
,
didChangeDependencies
;
final
void
Function
(
Bind
Wrapp
er
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
final
void
Function
(
Binder
<
T
>
oldWidget
,
BindElement
<
T
>
state
)?
didUpdateWidget
;
final
T
?
init
;
...
...
lib/get_state_manager/src/simple/simple_builder.dart
View file @
f213f4d
...
...
@@ -45,7 +45,6 @@ class _ValueBuilderState<T> extends State<ValueBuilder<T>> {
T
value
;
_ValueBuilderState
(
this
.
value
);
@override
Widget
build
(
BuildContext
context
)
=>
widget
.
builder
(
value
,
updater
);
...
...
@@ -92,17 +91,27 @@ abstract class ObxStatelessWidget extends StatelessWidget {
/// a Component that can track changes in a reactive variable
mixin
ObserverComponent
on
ComponentElement
{
final
disposers
=
<
Disposer
>[];
List
<
Disposer
>?
disposers
=
<
Disposer
>[];
void
getUpdate
()
{
if
(
disposers
!=
null
)
{
markNeedsBuild
();
}
}
@override
Widget
build
()
=>
NotifierManager
.
instance
.
exchange
(
disposers
,
markNeedsBuild
,
super
.
build
);
Widget
build
()
{
return
Notifier
.
instance
.
append
(
NotifyData
(
disposers:
disposers
!,
updater:
getUpdate
),
super
.
build
);
}
@override
void
unmount
()
{
super
.
unmount
();
for
(
final
disposer
in
disposers
)
{
for
(
final
disposer
in
disposers
!
)
{
disposer
();
}
disposers
!.
clear
();
disposers
=
null
;
}
}
...
...
lib/get_utils/src/extensions/context_extensions.dart
View file @
f213f4d
import
'package:collection/collection.dart'
;
import
'package:flutter/material.dart'
;
extension
ContextExt
ensionss
on
BuildContext
{
extension
ContextExt
on
BuildContext
{
/// The same of [MediaQuery.of(context).size]
Size
get
mediaQuerySize
=>
MediaQuery
.
of
(
this
).
size
;
...
...
@@ -105,8 +105,8 @@ extension ContextExtensionss on BuildContext {
/// True if the width is higher than 600p
bool
get
isPhoneOrWider
=>
width
>=
600
;
/// same as [isPhoneOrLess]
bool
get
isPhone
=>
isPhoneOrLess
;
/// True if the shortestSide is smaller than 600p
bool
get
isPhone
=>
(
mediaQueryShortestSide
<
600
);
/// True if the width is smaller than 600p
bool
get
isSmallTabletOrLess
=>
width
<=
600
;
...
...
@@ -114,8 +114,11 @@ extension ContextExtensionss on BuildContext {
/// True if the width is higher than 600p
bool
get
isSmallTabletOrWider
=>
width
>=
600
;
/// same as [isSmallTabletOrLess]
bool
get
isSmallTablet
=>
isSmallTabletOrLess
;
/// True if the shortestSide is largest than 600p
bool
get
isSmallTablet
=>
(
mediaQueryShortestSide
>=
600
);
/// True if the shortestSide is largest than 720p
bool
get
isLargeTablet
=>
(
mediaQueryShortestSide
>=
720
);
/// True if the width is smaller than 720p
bool
get
isLargeTabletOrLess
=>
width
<=
720
;
...
...
@@ -123,11 +126,8 @@ extension ContextExtensionss on BuildContext {
/// True if the width is higher than 720p
bool
get
isLargeTabletOrWider
=>
width
>=
720
;
/// same as [isLargeTabletOrLess]
bool
get
isLargeTablet
=>
isLargeTabletOrLess
;
/// True if the current device is Tablet
bool
get
isTablet
=>
isSmallTablet
;
bool
get
isTablet
=>
isSmallTablet
||
isLargeTablet
;
/// True if the width is smaller than 1200p
bool
get
isDesktopOrLess
=>
width
<=
1200
;
...
...
lib/get_utils/src/extensions/dynamic_extensions.dart
View file @
f213f4d
import
'../get_utils/get_utils.dart'
;
extension
GetDynamicUtils
on
dynamic
{
@Deprecated
(
'isNull is deprecated and cannot be used, use "==" operator'
)
bool
get
isNull
=>
GetUtils
.
isNull
(
this
);
bool
?
get
isBlank
=>
GetUtils
.
isBlank
(
this
);
@Deprecated
(
...
...
lib/get_utils/src/extensions/string_extensions.dart
View file @
f213f4d
import
'../get_utils/get_utils.dart'
;
extension
GetStringUtils
on
String
{
/// Discover if the String is a valid number
bool
get
isNum
=>
GetUtils
.
isNum
(
this
);
/// Discover if the String is numeric only
bool
get
isNumericOnly
=>
GetUtils
.
isNumericOnly
(
this
);
String
numericOnly
({
bool
firstWordOnly
=
false
})
=>
GetUtils
.
numericOnly
(
this
,
firstWordOnly:
firstWordOnly
);
/// Discover if the String is alphanumeric only
bool
get
isAlphabetOnly
=>
GetUtils
.
isAlphabetOnly
(
this
);
/// Discover if the String is a boolean
bool
get
isBool
=>
GetUtils
.
isBool
(
this
);
/// Discover if the String is a vector
bool
get
isVectorFileName
=>
GetUtils
.
isVector
(
this
);
/// Discover if the String is a ImageFileName
bool
get
isImageFileName
=>
GetUtils
.
isImage
(
this
);
/// Discover if the String is a AudioFileName
bool
get
isAudioFileName
=>
GetUtils
.
isAudio
(
this
);
/// Discover if the String is a VideoFileName
bool
get
isVideoFileName
=>
GetUtils
.
isVideo
(
this
);
/// Discover if the String is a TxtFileName
bool
get
isTxtFileName
=>
GetUtils
.
isTxt
(
this
);
/// Discover if the String is a Document Word
bool
get
isDocumentFileName
=>
GetUtils
.
isWord
(
this
);
/// Discover if the String is a Document Excel
bool
get
isExcelFileName
=>
GetUtils
.
isExcel
(
this
);
/// Discover if the String is a Document Powerpoint
bool
get
isPPTFileName
=>
GetUtils
.
isPPT
(
this
);
/// Discover if the String is a APK File
bool
get
isAPKFileName
=>
GetUtils
.
isAPK
(
this
);
/// Discover if the String is a PDF file
bool
get
isPDFFileName
=>
GetUtils
.
isPDF
(
this
);
/// Discover if the String is a HTML file
bool
get
isHTMLFileName
=>
GetUtils
.
isHTML
(
this
);
/// Discover if the String is a URL file
bool
get
isURL
=>
GetUtils
.
isURL
(
this
);
/// Discover if the String is a Email
bool
get
isEmail
=>
GetUtils
.
isEmail
(
this
);
/// Discover if the String is a Phone Number
bool
get
isPhoneNumber
=>
GetUtils
.
isPhoneNumber
(
this
);
/// Discover if the String is a DateTime
bool
get
isDateTime
=>
GetUtils
.
isDateTime
(
this
);
/// Discover if the String is a MD5 Hash
bool
get
isMD5
=>
GetUtils
.
isMD5
(
this
);
/// Discover if the String is a SHA1 Hash
bool
get
isSHA1
=>
GetUtils
.
isSHA1
(
this
);
/// Discover if the String is a SHA256 Hash
bool
get
isSHA256
=>
GetUtils
.
isSHA256
(
this
);
/// Discover if the String is a bynary value
bool
get
isBinary
=>
GetUtils
.
isBinary
(
this
);
/// Discover if the String is a ipv4
bool
get
isIPv4
=>
GetUtils
.
isIPv4
(
this
);
bool
get
isIPv6
=>
GetUtils
.
isIPv6
(
this
);
/// Discover if the String is a Hexadecimal
bool
get
isHexadecimal
=>
GetUtils
.
isHexadecimal
(
this
);
/// Discover if the String is a palindrom
bool
get
isPalindrom
=>
GetUtils
.
isPalindrom
(
this
);
/// Discover if the String is a passport number
bool
get
isPassport
=>
GetUtils
.
isPassport
(
this
);
/// Discover if the String is a currency
bool
get
isCurrency
=>
GetUtils
.
isCurrency
(
this
);
/// Discover if the String is a CPF number
bool
get
isCpf
=>
GetUtils
.
isCpf
(
this
);
/// Discover if the String is a CNPJ number
bool
get
isCnpj
=>
GetUtils
.
isCnpj
(
this
);
/// Discover if the String is a case insensitive
bool
isCaseInsensitiveContains
(
String
b
)
=>
GetUtils
.
isCaseInsensitiveContains
(
this
,
b
);
/// Discover if the String is a case sensitive and contains any value
bool
isCaseInsensitiveContainsAny
(
String
b
)
=>
GetUtils
.
isCaseInsensitiveContainsAny
(
this
,
b
);
/// capitalize the String
String
?
get
capitalize
=>
GetUtils
.
capitalize
(
this
);
/// Capitalize the first letter of the String
String
?
get
capitalizeFirst
=>
GetUtils
.
capitalizeFirst
(
this
);
/// remove all whitespace from the String
String
get
removeAllWhitespace
=>
GetUtils
.
removeAllWhitespace
(
this
);
/// converter the String
String
?
get
camelCase
=>
GetUtils
.
camelCase
(
this
);
/// Discover if the String is a valid URL
String
?
get
paramCase
=>
GetUtils
.
paramCase
(
this
);
String
numericOnly
({
bool
firstWordOnly
=
false
})
=>
GetUtils
.
numericOnly
(
this
,
firstWordOnly:
firstWordOnly
);
/// add segments to the String
String
createPath
([
Iterable
?
segments
])
{
final
path
=
startsWith
(
'/'
)
?
this
:
'/
$this
'
;
return
GetUtils
.
createPath
(
path
,
segments
);
...
...
lib/get_utils/src/widgets/otimized_listview.dart
0 → 100644
View file @
f213f4d
import
'package:flutter/material.dart'
;
class
OtimizedListView
<
T
>
extends
StatelessWidget
{
final
List
<
T
>
list
;
final
Axis
scrollDirection
;
final
bool
reverse
;
final
ScrollController
?
controller
;
final
bool
?
primary
;
final
ScrollPhysics
?
physics
;
final
bool
shrinkWrap
;
final
Widget
onEmpty
;
final
int
lenght
;
final
Widget
Function
(
BuildContext
context
,
ValueKey
key
,
T
item
)
builder
;
const
OtimizedListView
({
Key
?
key
,
required
this
.
list
,
required
this
.
builder
,
this
.
scrollDirection
=
Axis
.
vertical
,
this
.
reverse
=
false
,
this
.
controller
,
this
.
primary
,
this
.
physics
,
this
.
onEmpty
=
const
SizedBox
.
shrink
(),
this
.
shrinkWrap
=
false
,
})
:
lenght
=
list
.
length
,
super
(
key:
key
);
@override
Widget
build
(
BuildContext
context
)
{
if
(
list
.
isEmpty
)
return
onEmpty
;
return
CustomScrollView
(
controller:
controller
,
reverse:
reverse
,
scrollDirection:
scrollDirection
,
primary:
primary
,
physics:
physics
,
shrinkWrap:
shrinkWrap
,
slivers:
<
Widget
>[
SliverList
(
delegate:
SliverChildBuilderDelegate
(
(
context
,
i
)
{
final
item
=
list
[
i
];
final
key
=
ValueKey
(
item
);
return
builder
(
context
,
key
,
item
);
},
childCount:
list
.
length
,
addAutomaticKeepAlives:
true
,
findChildIndexCallback:
(
key
)
{
return
list
.
indexWhere
((
m
)
=>
m
==
(
key
as
ValueKey
<
T
>).
value
);
},
),
),
],
);
}
}
...
...
test/state_manager/get_mixin_state_test.dart
View file @
f213f4d
import
'package:flutter/material.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:get/get.dart'
;
import
'package:get/get_state_manager/src/simple/mixin_builder.dart'
;
void
main
(
)
{
testWidgets
(
"MixinBuilder
smoke test
"
,
(
tester
)
async
{
testWidgets
(
"MixinBuilder
with reactive and not reactive
"
,
(
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
home:
MixinBuilder
<
Controller
>(
...
...
@@ -35,6 +36,10 @@ void main() {
TextButton
(
child:
Text
(
"increment"
),
onPressed:
()
=>
controller
.
increment
(),
),
TextButton
(
child:
Text
(
"increment2"
),
onPressed:
()
=>
controller
.
increment2
(),
)
],
);
...
...
@@ -62,6 +67,12 @@ void main() {
await
tester
.
pump
();
expect
(
find
.
text
(
"Count: 2"
),
findsOneWidget
);
await
tester
.
tap
(
find
.
text
(
'increment2'
));
await
tester
.
pump
();
expect
(
find
.
text
(
"Count2: 1"
),
findsOneWidget
);
});
// testWidgets(
...
...
Please
register
or
login
to post a comment