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
Jonatas
2020-10-25 16:03:45 -0300
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
7146b6a53c0648104e4f623385deaff055e0036a
7146b6a5
1 parent
c3b22643
improve framework structure, added StateMixin, prepare to getx 4.0
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
216 additions
and
290 deletions
example/lib/pages/home/presentation/controllers/home_controller.dart
example/lib/pages/home/presentation/views/country_view.dart
example/lib/pages/home/presentation/views/home_view.dart
example/test/main_test.dart
lib/get_instance/src/lifecycle.dart
lib/get_state_manager/src/rx_flutter/rx_disposable.dart
lib/get_state_manager/src/rx_flutter/rx_notifier.dart
lib/get_state_manager/src/simple/get_state.dart
lib/get_state_manager/src/simple/immutable_state.dart
lib/get_state_manager/src/simple/list_notifier.dart
lib/get_state_manager/src/simple/simple_builder.dart
pubspec.yaml
test/instance/get_instance_test.dart
example/lib/pages/home/presentation/controllers/home_controller.dart
View file @
7146b6a
...
...
@@ -3,43 +3,22 @@ import 'package:get/get.dart';
import
'../../domain/adapters/repository_adapter.dart'
;
import
'../../domain/entity/cases_model.dart'
;
enum
Status
{
loading
,
success
,
error
}
class
HomeController
extends
GetxController
{
class
HomeController
extends
GetxController
with
StatusMixin
<
CasesModel
>
{
HomeController
({
this
.
homeRepository
});
/// inject repo abstraction dependency
final
IHomeRepository
homeRepository
;
/// create a reactive status from request with initial value = loading
final
status
=
Status
.
loading
.
obs
;
/// create a reactive CasesModel. CasesModel().obs has same result
final
cases
=
Rx
<
CasesModel
>();
/// When the controller is initialized, make the http request
@override
void
onInit
()
{
super
.
onInit
();
fetchDataFromApi
();
}
/// fetch cases from Api
Future
<
void
>
fetchDataFromApi
()
async
{
/// When the repository returns the value, change the status to success,
/// and fill in "cases"
return
homeRepository
.
getCases
().
then
(
(
data
)
{
cases
(
data
);
status
(
Status
.
success
);
},
/// In case of error, print the error and change the status
/// to Status.error
onError:
(
err
)
{
print
(
"
$err
"
);
return
status
(
Status
.
error
);
},
);
// show loading on start, data on success
// and error message on error with 0 boilerplate
homeRepository
.
getCases
().
then
((
data
)
{
change
(
data
,
status:
RxStatus
.
success
());
},
onError:
(
err
)
{
change
(
null
,
status:
RxStatus
.
error
(
err
.
toString
()));
});
}
}
...
...
example/lib/pages/home/presentation/views/country_view.dart
View file @
7146b6a
...
...
@@ -29,9 +29,9 @@ class CountryView extends GetView<HomeController> {
),
body:
Center
(
child:
ListView
.
builder
(
itemCount:
controller
.
cases
.
value
.
countries
.
length
,
itemCount:
controller
.
value
.
countries
.
length
,
itemBuilder:
(
context
,
index
)
{
final
country
=
controller
.
cases
.
value
.
countries
[
index
];
final
country
=
controller
.
value
.
countries
[
index
];
return
ListTile
(
onTap:
()
{
Get
.
toNamed
(
'/details'
,
arguments:
country
);
...
...
example/lib/pages/home/presentation/views/home_view.dart
View file @
7146b6a
...
...
@@ -27,11 +27,8 @@ class HomeView extends GetView<HomeController> {
centerTitle:
true
,
),
body:
Center
(
child:
Obx
(
()
{
final
status
=
controller
.
status
.
value
;
if
(
status
==
Status
.
loading
)
return
CircularProgressIndicator
();
if
(
status
==
Status
.
error
)
return
Text
(
'Error on connection :('
);
child:
controller
(
(
state
)
{
return
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
...
...
@@ -45,7 +42,7 @@ class HomeView extends GetView<HomeController> {
),
),
Text
(
'
${
controller.cases.valu
e.global.totalConfirmed}
'
,
'
${
stat
e.global.totalConfirmed}
'
,
style:
TextStyle
(
fontSize:
45
,
fontWeight:
FontWeight
.
bold
),
),
SizedBox
(
...
...
@@ -58,7 +55,7 @@ class HomeView extends GetView<HomeController> {
),
),
Text
(
'
${
controller.cases.valu
e.global.totalDeaths}
'
,
'
${
stat
e.global.totalDeaths}
'
,
style:
TextStyle
(
fontSize:
45
,
fontWeight:
FontWeight
.
bold
),
),
SizedBox
(
...
...
example/test/main_test.dart
View file @
7146b6a
...
...
@@ -59,18 +59,18 @@ void main() {
expect
(
controller
.
initialized
,
true
);
/// check initial Status
expect
(
controller
.
status
.
value
,
Status
.
loading
);
expect
(
controller
.
status
.
isLoading
,
true
);
/// await time request
await
Future
.
delayed
(
Duration
(
milliseconds:
100
));
if
(
controller
.
status
.
value
==
Status
.
error
)
{
expect
(
controller
.
cases
.
value
,
null
);
if
(
controller
.
status
.
isError
)
{
expect
(
controller
.
value
,
null
);
}
if
(
controller
.
status
.
value
==
Status
.
success
)
{
expect
(
controller
.
cases
.
value
.
global
.
totalDeaths
,
100
);
expect
(
controller
.
cases
.
value
.
global
.
totalConfirmed
,
200
);
if
(
controller
.
status
.
isSuccess
)
{
expect
(
controller
.
value
.
global
.
totalDeaths
,
100
);
expect
(
controller
.
value
.
global
.
totalConfirmed
,
200
);
}
});
...
...
lib/get_instance/src/lifecycle.dart
View file @
7146b6a
import
'package:meta/meta.dart'
;
import
'../../get_core/get_core.dart'
;
/// Special callable class to keep the contract of a regular method, and avoid
...
...
@@ -18,37 +17,34 @@ class _InternalFinalCallback<T> {
/// ```dart
/// class SomeController with GetLifeCycle {
/// SomeController() {
///
init
LifeCycle();
///
configure
LifeCycle();
/// }
/// }
/// ```
mixin
GetLifeCycle
{
/// The `initLifeCycle` works as a constructor for the [GetLifeCycle]
///
/// This method must be invoked in the constructor of the implementation
void
initLifeCycle
()
{
onStart
.
_callback
=
_onStart
;
onDelete
.
_callback
=
_onDelete
;
}
mixin
GetLifeCycleBase
{
/// Called at the exact moment the widget is allocated in memory.
/// It uses an internal "callable" type, to avoid any @overrides in subclases.
/// This method should be internal and is required to define the
/// lifetime cycle of the subclass.
final
onStart
=
_InternalFinalCallback
<
void
>();
// /// The `configureLifeCycle` works as a constructor for the [GetLifeCycle]
// ///
// /// This method must be invoked in the constructor of the implementation
// void configureLifeCycle() {
// if (_initialized) return;
// }
/// Internal callback that starts the cycle of this controller.
final
onDelete
=
_InternalFinalCallback
<
void
>();
/// Called immediately after the widget is allocated in memory.
/// You might use this to initialize something for the controller.
@mustCallSuper
void
onInit
()
{}
/// Called 1 frame after onInit(). It is the perfect place to enter
/// navigation events, like snackbar, dialogs, or a new route, or
/// async request.
@mustCallSuper
void
onReady
()
{}
/// Called before [onDelete] method. [onClose] might be used to
...
...
@@ -57,7 +53,6 @@ mixin 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.
@mustCallSuper
void
onClose
()
{}
bool
_initialized
=
false
;
...
...
@@ -83,6 +78,26 @@ mixin GetLifeCycle {
_isClosed
=
true
;
onClose
();
}
void
$configureLifeCycle
()
{
_checkIfAlreadyConfigured
();
onStart
.
_callback
=
_onStart
;
onDelete
.
_callback
=
_onDelete
;
}
void
_checkIfAlreadyConfigured
()
{
if
(
_initialized
)
{
throw
"""You can only call configureLifeCycle once.
The proper place to insert it is in your class's constructor
that inherits GetLifeCycle."""
;
}
}
}
abstract
class
GetLifeCycle
with
GetLifeCycleBase
{
GetLifeCycle
()
{
$configureLifeCycle
();
}
}
/// Allow track difference between GetxServices and GetxControllers
...
...
lib/get_state_manager/src/rx_flutter/rx_disposable.dart
View file @
7146b6a
...
...
@@ -10,11 +10,7 @@ import '../../../get_instance/src/lifecycle.dart';
/// it is Get.reset().
abstract
class
GetxService
extends
DisposableInterface
with
GetxServiceMixin
{}
abstract
class
DisposableInterface
with
GetLifeCycle
{
DisposableInterface
()
{
initLifeCycle
();
}
abstract
class
DisposableInterface
extends
GetLifeCycle
{
/// Called immediately after the widget is allocated in memory.
/// You might use this to initialize something for the controller.
@override
...
...
@@ -29,7 +25,9 @@ abstract class DisposableInterface with GetLifeCycle {
/// async request.
@override
@mustCallSuper
void
onReady
()
{}
void
onReady
()
{
super
.
onReady
();
}
/// Called before [onDelete] method. [onClose] might be used to
/// dispose resources used by the controller. Like closing events,
...
...
@@ -38,5 +36,7 @@ abstract class DisposableInterface with GetLifeCycle {
/// like TextEditingControllers, AnimationControllers.
/// Might be useful as well to persist some data on disk.
@override
void
onClose
()
{}
void
onClose
()
{
super
.
onClose
();
}
}
...
...
lib/get_state_manager/src/rx_flutter/rx_notifier.dart
View file @
7146b6a
...
...
@@ -5,29 +5,77 @@ import '../../../instance_manager.dart';
import
'../../get_state_manager.dart'
;
import
'../simple/list_notifier.dart'
;
class
Value
<
T
>
extends
ListNotifier
implements
ValueListenable
<
T
>
{
Value
(
this
.
_value
);
mixin
StatusMixin
<
T
>
on
ListNotifier
{
T
_value
;
RxStatus
_status
;
bool
_isNullOrEmpty
(
dynamic
val
)
{
if
(
val
==
null
)
return
true
;
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
(
_value
)
?
RxStatus
.
loading
()
:
RxStatus
.
success
();
}
RxStatus
get
status
{
notifyChildrens
();
return
_status
??=
_status
=
RxStatus
.
loading
();
}
T
get
value
{
notifyChildrens
();
return
_value
;
}
@override
String
toString
()
=>
value
.
toString
();
T
_value
;
set
value
(
T
newValue
)
{
if
(
_value
==
newValue
)
return
;
_value
=
newValue
;
updater
();
refresh
();
}
@protected
void
change
(
T
newState
,
{
RxStatus
status
})
{
var
_canUpdate
=
false
;
if
(
status
!=
null
)
{
_status
=
status
;
_canUpdate
=
true
;
}
if
(
newState
!=
_value
)
{
_value
=
newState
;
_canUpdate
=
true
;
}
if
(
_canUpdate
)
{
refresh
();
}
}
}
class
Value
<
T
>
extends
ListNotifier
with
StatusMixin
<
T
>
implements
ValueListenable
<
T
>
{
Value
(
T
val
)
{
_value
=
val
;
_fillEmptyStatus
();
}
void
update
(
void
fn
(
T
value
))
{
fn
(
value
);
updater
();
refresh
();
}
@override
String
toString
()
=>
value
.
toString
();
dynamic
toJson
()
=>
(
value
as
dynamic
)?.
toJson
();
}
extension
ReactiveT
<
T
>
on
T
{
...
...
@@ -36,10 +84,9 @@ extension ReactiveT<T> on T {
typedef
Condition
=
bool
Function
();
abstract
class
GetNotifier
<
T
>
extends
Value
<
T
>
with
GetLifeCycle
{
abstract
class
GetNotifier
<
T
>
extends
Value
<
T
>
with
GetLifeCycle
Base
{
GetNotifier
(
T
initial
)
:
super
(
initial
)
{
initLifeCycle
();
_fillEmptyStatus
();
$configureLifeCycle
();
}
@override
...
...
@@ -48,32 +95,9 @@ abstract class GetNotifier<T> extends Value<T> with GetLifeCycle {
super
.
onInit
();
SchedulerBinding
.
instance
?.
addPostFrameCallback
((
_
)
=>
onReady
());
}
}
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
{
notifyChildrens
();
return
_status
;
}
extension
StateExt
<
T
>
on
StatusMixin
<
T
>
{
Widget
call
(
NotifierBuilder
<
T
>
widget
,
{
Widget
onError
,
Widget
onLoading
})
{
assert
(
widget
!=
null
);
return
SimpleBuilder
(
builder:
(
_
)
{
...
...
@@ -86,24 +110,6 @@ abstract class GetNotifier<T> extends Value<T> with GetLifeCycle {
}
});
}
@protected
void
change
(
T
newState
,
{
RxStatus
status
})
{
var
_canUpdate
=
false
;
if
(
status
!=
null
)
{
_status
=
status
;
_canUpdate
=
true
;
}
if
(
newState
!=
_value
)
{
_value
=
newState
;
_canUpdate
=
true
;
}
if
(
_canUpdate
)
{
updater
();
}
}
dynamic
toJson
()
=>
(
value
as
dynamic
)?.
toJson
();
}
class
RxStatus
{
...
...
lib/get_state_manager/src/simple/get_state.dart
View file @
7146b6a
import
'dart:collection'
;
import
'package:flutter/material.dart'
;
import
'../../../get_core/get_core.dart'
;
import
'../../../get_instance/src/get_instance.dart'
;
import
'../../get_state_manager.dart'
;
// Changed to VoidCallback.
//typedef Disposer = void Function();
// replacing StateSetter, return if the Widget is mounted for extra validation.
// if it brings overhead the extra call,
typedef
GetStateUpdate
=
void
Function
();
//typedef GetStateUpdate = void Function(VoidCallback fn);
import
'list_notifier.dart'
;
/// Complies with [GetStateUpdater]
///
...
...
@@ -31,14 +23,8 @@ mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> {
}
}
class
GetxController
extends
DisposableInterface
{
final
_updaters
=
<
GetStateUpdate
>[];
// final _updatersIds = HashMap<String, StateSetter>(); //<old>
final
_updatersIds
=
HashMap
<
String
,
GetStateUpdate
>();
final
_updatersGroupIds
=
HashMap
<
String
,
List
<
GetStateUpdate
>>();
// ignore: prefer_mixin
class
GetxController
extends
DisposableInterface
with
ListNotifier
{
/// Rebuilds [GetBuilder] each time you call [update()];
/// Can take a List of [ids], that will only update the matching
/// `GetBuilder( id: )`,
...
...
@@ -49,73 +35,13 @@ class GetxController extends DisposableInterface {
return
;
}
if
(
ids
==
null
)
{
// _updaters?.forEach((rs) => rs(() {})); //<old>
for
(
final
updater
in
_updaters
)
{
updater
();
}
refresh
();
}
else
{
// @jonny, remove this commented code if it's not more optimized.
// for (final id in ids) {
// if (_updatersIds[id] != null) _updatersIds[id]();
// if (_updatersGroupIds[id] != null)
// for (final rs in _updatersGroupIds[id]) rs();
// }
for
(
final
id
in
ids
)
{
_updatersIds
[
id
]?.
call
();
// ignore: avoid_function_literals_in_foreach_calls
_updatersGroupIds
[
id
]?.
forEach
((
rs
)
=>
rs
());
refreshGroup
(
id
);
}
}
}
// VoidCallback addListener(StateSetter listener) {//<old>
VoidCallback
addListener
(
GetStateUpdate
listener
)
{
_updaters
.
add
(
listener
);
return
()
=>
_updaters
.
remove
(
listener
);
}
// VoidCallback addListenerId(String key, StateSetter listener) {//<old>
VoidCallback
addListenerId
(
String
key
,
GetStateUpdate
listener
)
{
// _printCurrentIds();
if
(
_updatersIds
.
containsKey
(
key
))
{
_updatersGroupIds
[
key
]
??=
<
GetStateUpdate
>[];
_updatersGroupIds
[
key
].
add
(
listener
);
return
()
{
_updatersGroupIds
[
key
].
remove
(
listener
);
};
}
else
{
_updatersIds
[
key
]
=
listener
;
return
()
=>
_updatersIds
.
remove
(
key
);
}
}
/// To dispose an [id] from future updates(), this ids are registered
/// by [GetBuilder()] or similar, so is a way to unlink the state change with
/// the Widget from the Controller.
void
disposeId
(
String
id
)
{
_updatersIds
.
remove
(
id
);
_updatersGroupIds
.
remove
(
id
);
}
/// Remove this after checking the new implementation makes sense.
/// Uncomment this if you wanna control the removal of ids..
/// bool _debugging = false;
/// Future<void> _printCurrentIds() async {
/// if (_debugging) return;
/// _debugging = true;
/// print('about to debug...');
/// await Future.delayed(Duration(milliseconds: 10));
/// int totalGroups = 0;
/// _updatersGroupIds.forEach((key, value) {
/// totalGroups += value.length;
/// });
/// int totalIds = _updatersIds.length;
/// print(
/// 'Total: ${totalIds + totalGroups},'+
/// 'in groups:$totalGroups, solo ids:$totalIds',);
/// _debugging = false;
/// }
}
typedef
GetControllerBuilder
<
T
extends
DisposableInterface
>
=
Widget
Function
(
...
...
@@ -187,10 +113,6 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>>
controller
?.
onStart
();
}
// if (widget.global && Get.smartManagement ==
//SmartManagement.onlyBuilder) {
// controller?.onStart();
// }
_subscribeToController
();
}
...
...
@@ -200,20 +122,10 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>>
void
_subscribeToController
()
{
remove
?.
call
();
remove
=
(
widget
.
id
==
null
)
// ? controller?.addListener(setState) //<old>
// : controller?.addListenerId(widget.id, setState); //<old>
?
controller
?.
addListener
(
getUpdate
)
:
controller
?.
addListenerId
(
widget
.
id
,
getUpdate
);
}
/// Sample for [GetStateUpdate] when you don't wanna
/// use [GetStateHelper mixin].
/// bool _getUpdater() {
/// final _mounted = mounted;
/// if (_mounted) setState(() {});
/// return _mounted;
/// }
@override
void
dispose
()
{
super
.
dispose
();
...
...
@@ -249,26 +161,6 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>>
Widget
build
(
BuildContext
context
)
=>
widget
.
builder
(
controller
);
}
/// This is a experimental feature.
/// Meant to be used with SimpleBuilder, it auto-registers the variable
/// like Rx() does with Obx().
// class Value<T> extends GetxController {
// Value([this._value]);
// T _value;
// T get value {
// TaskManager.instance.notify(_updaters);
// return _value;
// }
// set value(T newValue) {
// if (_value == newValue) return;
// _value = newValue;
// update();
// }
// }
/// It's Experimental class, the Api can be change
abstract
class
GetState
<
T
>
extends
GetxController
{
GetState
(
T
initialValue
)
{
...
...
lib/get_state_manager/src/simple/immutable_state.dart
View file @
7146b6a
...
...
@@ -146,5 +146,3 @@
// return widget.builder(controller.state);
// }
//}
...
...
lib/get_state_manager/src/simple/list_notifier.dart
View file @
7146b6a
import
'dart:collection'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/widgets.dart'
;
import
'simple_builder.dart'
;
// This callback remove the listener on addListener function
typedef
Disposer
=
void
Function
();
// replacing StateSetter, return if the Widget is mounted for extra validation.
// if it brings overhead the extra call,
typedef
GetStateUpdate
=
void
Function
();
class
ListNotifier
implements
Listenable
{
List
<
VoidCallback
>
_listeners
=
<
VoidCallback
>[];
List
<
GetStateUpdate
>
_updaters
=
<
GetStateUpdate
>[];
HashMap
<
String
,
List
<
GetStateUpdate
>>
_updatersGroupIds
=
HashMap
<
String
,
List
<
GetStateUpdate
>>();
@protected
void
updater
()
{
void
refresh
()
{
assert
(
_debugAssertNotDisposed
());
for
(
var
element
in
_
listen
ers
)
{
for
(
var
element
in
_
updat
ers
)
{
element
();
}
}
@protected
void
refreshGroup
(
String
id
)
{
assert
(
_debugAssertNotDisposed
());
if
(
_updatersGroupIds
.
containsKey
(
id
))
{
for
(
var
item
in
_updatersGroupIds
[
id
])
{
item
();
}
}
}
bool
_debugAssertNotDisposed
()
{
assert
(()
{
if
(
_
listen
ers
==
null
)
{
if
(
_
updat
ers
==
null
)
{
throw
FlutterError
(
'''A
$runtimeType
was used after being disposed.
\n
'
Once
you
have
called
dispose
()
on
a
$runtimeType
,
it
can
no
longer
be
used
.
''');
}
...
...
@@ -26,29 +46,87 @@ class ListNotifier implements Listenable {
@protected
void notifyChildrens() {
TaskManager.instance.notify(_
listen
ers);
TaskManager.instance.notify(_
updat
ers);
}
bool get hasListeners {
assert(_debugAssertNotDisposed());
return _
listen
ers.isNotEmpty;
return _
updat
ers.isNotEmpty;
}
@override
void
add
Listener(VoidCallback listener) {
void
remove
Listener(VoidCallback listener) {
assert(_debugAssertNotDisposed());
_
listeners.add
(listener);
_
updaters.remove
(listener);
}
@override
void removeListener(VoidCallback listener) {
void removeListenerId(String id, VoidCallback listener) {
assert(_debugAssertNotDisposed());
_listeners.remove(listener);
if (_updatersGroupIds.containsKey(id)) {
_updatersGroupIds[id].remove(listener);
}
_updaters.remove(listener);
}
@mustCallSuper
void dispose() {
assert(_debugAssertNotDisposed());
_listeners = null;
_updaters = null;
_updatersGroupIds = null;
}
@override
Disposer addListener(GetStateUpdate listener) {
assert(_debugAssertNotDisposed());
_updaters.add(listener);
return () => _updaters.remove(listener);
}
Disposer addListenerId(String key, GetStateUpdate listener) {
_updatersGroupIds[key] ??= <GetStateUpdate>[];
_updatersGroupIds[key].add(listener);
return () => _updatersGroupIds[key].remove(listener);
}
/// To dispose an [id] from future updates(), this ids are registered
/// by [GetBuilder()] or similar, so is a way to unlink the state change with
/// the Widget from the Controller.
void disposeId(String id) {
_updatersGroupIds.remove(id);
}
}
class TaskManager {
TaskManager._();
static TaskManager _instance;
static TaskManager get instance => _instance ??= TaskManager._();
GetStateUpdate _setter;
List<VoidCallback> _remove;
void notify(List<GetStateUpdate> _updaters) {
if (_setter != null) {
if (!_updaters.contains(_setter)) {
_updaters.add(_setter);
_remove.add(() => _updaters.remove(_setter));
}
}
}
Widget exchange(
List<VoidCallback> disposers,
GetStateUpdate setState,
Widget Function(BuildContext) builder,
BuildContext context,
) {
_remove = disposers;
_setter = setState;
final result = builder(context);
_remove = null;
_setter = null;
return result;
}
}
...
...
lib/get_state_manager/src/simple/simple_builder.dart
View file @
7146b6a
import
'dart:async'
;
import
'package:flutter/widgets.dart'
;
import
'get_state.dart'
;
import
'list_notifier.dart'
;
typedef
ValueBuilderUpdateCallback
<
T
>
=
void
Function
(
T
snapshot
);
typedef
ValueBuilderBuilder
<
T
>
=
Widget
Function
(
...
...
@@ -87,7 +88,7 @@ class SimpleBuilder extends StatefulWidget {
class
_SimpleBuilderState
extends
State
<
SimpleBuilder
>
with
GetStateUpdaterMixin
{
final
disposers
=
<
VoidCallback
>[];
final
disposers
=
<
Disposer
>[];
@override
void
dispose
()
{
...
...
@@ -107,38 +108,3 @@ class _SimpleBuilderState extends State<SimpleBuilder>
);
}
}
class
TaskManager
{
TaskManager
.
_
();
static
TaskManager
_instance
;
static
TaskManager
get
instance
=>
_instance
??=
TaskManager
.
_
();
GetStateUpdate
_setter
;
List
<
VoidCallback
>
_remove
;
void
notify
(
List
<
GetStateUpdate
>
_updaters
)
{
if
(
_setter
!=
null
)
{
if
(!
_updaters
.
contains
(
_setter
))
{
_updaters
.
add
(
_setter
);
_remove
.
add
(()
=>
_updaters
.
remove
(
_setter
));
}
}
}
Widget
exchange
(
List
<
VoidCallback
>
disposers
,
GetStateUpdate
setState
,
Widget
Function
(
BuildContext
)
builder
,
BuildContext
context
,
)
{
_remove
=
disposers
;
_setter
=
setState
;
final
result
=
builder
(
context
);
_remove
=
null
;
_setter
=
null
;
return
result
;
}
}
...
...
pubspec.yaml
View file @
7146b6a
...
...
@@ -9,7 +9,6 @@ environment:
dependencies
:
flutter
:
sdk
:
flutter
meta
:
1.3.0-nullsafety.3
dev_dependencies
:
flutter_test
:
...
...
test/instance/get_instance_test.dart
View file @
7146b6a
...
...
@@ -9,11 +9,7 @@ class Mock {
}
}
class
DisposableController
with
GetLifeCycle
{
DisposableController
()
{
initLifeCycle
();
}
}
class
DisposableController
extends
GetLifeCycle
{}
// ignore: one_member_abstracts
abstract
class
Service
{
...
...
Please
register
or
login
to post a comment