Rodrigo Lopez Peker

- comment Obx functionality.

- close subscription in Obx
- added the experimental ObxValue() widget to manage local states based on Rx.
- added experimental ValueBuilder(), analogue to ObxValue(), but uses a simpler StatefulWidget with a callback.
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:get/src/state_manager/rx/rx_interface.dart';
import 'rx_impl.dart';
Widget obx(Widget Function() builder) {
... ... @@ -24,6 +27,13 @@ class Obxx extends StatelessWidget {
}
}
/// The simplest reactive widget in GetX.
///
/// Just pass your Rx variable in the root scope of the callback to have it
/// automatically registered for changes.
///
/// final _name = "GetX".obs;
/// Obx(() => Text( _name.value )),... ;
class Obx extends StatefulWidget {
final Widget Function() builder;
... ... @@ -33,6 +43,7 @@ class Obx extends StatefulWidget {
class _ObxState extends State<Obx> {
RxInterface _observer;
StreamSubscription subs;
_ObxState() {
_observer = Rx();
... ... @@ -40,12 +51,13 @@ class _ObxState extends State<Obx> {
@override
void initState() {
_observer.subject.stream.listen((data) => setState(() {}));
subs = _observer.subject.stream.listen((data) => setState(() {}));
super.initState();
}
@override
void dispose() {
subs.cancel();
_observer.close();
super.dispose();
}
... ... @@ -71,3 +83,59 @@ class _ObxState extends State<Obx> {
@override
Widget build(BuildContext context) => notifyChilds;
}
/// Similar to Obx, but manages a local state.
/// Pass the initial data in constructor.
/// Useful for simple local states, like toggles, visibility, themes,
/// button states, etc.
/// Sample:
/// ObxValue((data) => Switch(
/// value: data.value,
/// onChanged: (flag) => data.value = flag,
/// ),
/// false.obs,
/// ),
// TODO: change T to a proper Rx interfase, that includes the accessor for ::value
class ObxValue<T extends RxInterface> extends StatefulWidget {
final Widget Function(T) builder;
final T data;
const ObxValue(this.builder, this.data, {Key key}) : super(key: key);
_ObxValueState createState() => _ObxValueState();
}
class _ObxValueState extends State<ObxValue> {
RxInterface _observer;
StreamSubscription subs;
_ObxValueState() {
_observer = Rx();
}
@override
void initState() {
subs = _observer.subject.stream.listen((data) => setState(() {}));
super.initState();
}
@override
void dispose() {
subs.cancel();
_observer.close();
super.dispose();
}
Widget get notifyChilds {
final observer = getObs;
getObs = _observer;
// observable is implicity taken from the constructor.
final result = widget.builder(widget.data);
getObs = observer;
return result;
}
@override
Widget build(BuildContext context) => notifyChilds;
}
... ...
import 'dart:async';
import 'dart:collection';
import 'package:flutter/widgets.dart';
import 'get_state.dart';
typedef ValueBuilderUpdateCallback<T> = void Function(T snapshot);
typedef ValueBuilderBuilder<T> = Widget Function(
T snapshot, ValueBuilderUpdateCallback<T> updater);
/// Manages a local state like ObxValue, but uses a callback instead of a Rx value.
///
/// Sample:
/// ValueBuilder<bool>(
/// initialValue: false,
/// builder: (value, update) => Switch(
/// value: value,
/// onChanged: (flag) {
/// update( flag );
/// },),
/// onUpdate: (value) => print("Value updated: $value"),
/// ),
class ValueBuilder<T> extends StatefulWidget {
final T initialValue;
final ValueBuilderBuilder builder;
final void Function() onDispose;
final void Function(T) onUpdate;
const ValueBuilder({
Key key,
this.initialValue,
this.onDispose,
this.onUpdate,
@required this.builder,
}) : super(key: key);
@override
_ValueBuilderState<T> createState() => _ValueBuilderState<T>();
}
class _ValueBuilderState<T> extends State<ValueBuilder<T>> {
T value;
@override
void initState() {
super.initState();
value = widget.initialValue;
}
@override
Widget build(BuildContext context) => widget.builder(value, updater);
void updater(T newValue) {
if (widget.onUpdate != null) {
widget.onUpdate(newValue);
}
setState(() {
value = newValue;
});
}
@override
void dispose() {
super.dispose();
widget?.onDispose?.call();
if (value is ChangeNotifier) {
(value as ChangeNotifier)?.dispose();
} else if (value is StreamController) {
(value as StreamController)?.close();
}
value = null;
}
}
// It's a experimental feature
class SimpleBuilder extends StatefulWidget {
final Widget Function(BuildContext) builder;
... ...