Jonny Borges
Committed by GitHub

Merge pull request #501 from roipeker/master

Added 2 new widgets to manage local state and some cleanup
  1 +import 'dart:async';
  2 +
1 import 'package:flutter/widgets.dart'; 3 import 'package:flutter/widgets.dart';
2 import 'package:get/src/state_manager/rx/rx_interface.dart'; 4 import 'package:get/src/state_manager/rx/rx_interface.dart';
  5 +
3 import 'rx_impl.dart'; 6 import 'rx_impl.dart';
4 7
5 Widget obx(Widget Function() builder) { 8 Widget obx(Widget Function() builder) {
@@ -24,6 +27,13 @@ class Obxx extends StatelessWidget { @@ -24,6 +27,13 @@ class Obxx extends StatelessWidget {
24 } 27 }
25 } 28 }
26 29
  30 +/// The simplest reactive widget in GetX.
  31 +///
  32 +/// Just pass your Rx variable in the root scope of the callback to have it
  33 +/// automatically registered for changes.
  34 +///
  35 +/// final _name = "GetX".obs;
  36 +/// Obx(() => Text( _name.value )),... ;
27 class Obx extends StatefulWidget { 37 class Obx extends StatefulWidget {
28 final Widget Function() builder; 38 final Widget Function() builder;
29 39
@@ -33,6 +43,7 @@ class Obx extends StatefulWidget { @@ -33,6 +43,7 @@ class Obx extends StatefulWidget {
33 43
34 class _ObxState extends State<Obx> { 44 class _ObxState extends State<Obx> {
35 RxInterface _observer; 45 RxInterface _observer;
  46 + StreamSubscription subs;
36 47
37 _ObxState() { 48 _ObxState() {
38 _observer = Rx(); 49 _observer = Rx();
@@ -40,12 +51,13 @@ class _ObxState extends State<Obx> { @@ -40,12 +51,13 @@ class _ObxState extends State<Obx> {
40 51
41 @override 52 @override
42 void initState() { 53 void initState() {
43 - _observer.subject.stream.listen((data) => setState(() {})); 54 + subs = _observer.subject.stream.listen((data) => setState(() {}));
44 super.initState(); 55 super.initState();
45 } 56 }
46 57
47 @override 58 @override
48 void dispose() { 59 void dispose() {
  60 + subs.cancel();
49 _observer.close(); 61 _observer.close();
50 super.dispose(); 62 super.dispose();
51 } 63 }
@@ -71,3 +83,59 @@ class _ObxState extends State<Obx> { @@ -71,3 +83,59 @@ class _ObxState extends State<Obx> {
71 @override 83 @override
72 Widget build(BuildContext context) => notifyChilds; 84 Widget build(BuildContext context) => notifyChilds;
73 } 85 }
  86 +
  87 +/// Similar to Obx, but manages a local state.
  88 +/// Pass the initial data in constructor.
  89 +/// Useful for simple local states, like toggles, visibility, themes,
  90 +/// button states, etc.
  91 +/// Sample:
  92 +/// ObxValue((data) => Switch(
  93 +/// value: data.value,
  94 +/// onChanged: (flag) => data.value = flag,
  95 +/// ),
  96 +/// false.obs,
  97 +/// ),
  98 +
  99 +// TODO: change T to a proper Rx interfase, that includes the accessor for ::value
  100 +class ObxValue<T extends RxInterface> extends StatefulWidget {
  101 + final Widget Function(T) builder;
  102 + final T data;
  103 +
  104 + const ObxValue(this.builder, this.data, {Key key}) : super(key: key);
  105 +
  106 + _ObxValueState createState() => _ObxValueState();
  107 +}
  108 +
  109 +class _ObxValueState extends State<ObxValue> {
  110 + RxInterface _observer;
  111 + StreamSubscription subs;
  112 +
  113 + _ObxValueState() {
  114 + _observer = Rx();
  115 + }
  116 +
  117 + @override
  118 + void initState() {
  119 + subs = _observer.subject.stream.listen((data) => setState(() {}));
  120 + super.initState();
  121 + }
  122 +
  123 + @override
  124 + void dispose() {
  125 + subs.cancel();
  126 + _observer.close();
  127 + super.dispose();
  128 + }
  129 +
  130 + Widget get notifyChilds {
  131 + final observer = getObs;
  132 + getObs = _observer;
  133 + // observable is implicity taken from the constructor.
  134 + final result = widget.builder(widget.data);
  135 + getObs = observer;
  136 + return result;
  137 + }
  138 +
  139 + @override
  140 + Widget build(BuildContext context) => notifyChilds;
  141 +}
  1 +import 'dart:async';
1 import 'dart:collection'; 2 import 'dart:collection';
  3 +
2 import 'package:flutter/widgets.dart'; 4 import 'package:flutter/widgets.dart';
  5 +
3 import 'get_state.dart'; 6 import 'get_state.dart';
4 7
  8 +typedef ValueBuilderUpdateCallback<T> = void Function(T snapshot);
  9 +typedef ValueBuilderBuilder<T> = Widget Function(
  10 + T snapshot, ValueBuilderUpdateCallback<T> updater);
  11 +
  12 +/// Manages a local state like ObxValue, but uses a callback instead of a Rx value.
  13 +///
  14 +/// Sample:
  15 +/// ValueBuilder<bool>(
  16 +/// initialValue: false,
  17 +/// builder: (value, update) => Switch(
  18 +/// value: value,
  19 +/// onChanged: (flag) {
  20 +/// update( flag );
  21 +/// },),
  22 +/// onUpdate: (value) => print("Value updated: $value"),
  23 +/// ),
  24 +class ValueBuilder<T> extends StatefulWidget {
  25 + final T initialValue;
  26 + final ValueBuilderBuilder builder;
  27 + final void Function() onDispose;
  28 + final void Function(T) onUpdate;
  29 +
  30 + const ValueBuilder({
  31 + Key key,
  32 + this.initialValue,
  33 + this.onDispose,
  34 + this.onUpdate,
  35 + @required this.builder,
  36 + }) : super(key: key);
  37 +
  38 + @override
  39 + _ValueBuilderState<T> createState() => _ValueBuilderState<T>();
  40 +}
  41 +
  42 +class _ValueBuilderState<T> extends State<ValueBuilder<T>> {
  43 + T value;
  44 +
  45 + @override
  46 + void initState() {
  47 + super.initState();
  48 + value = widget.initialValue;
  49 + }
  50 +
  51 + @override
  52 + Widget build(BuildContext context) => widget.builder(value, updater);
  53 +
  54 + void updater(T newValue) {
  55 + if (widget.onUpdate != null) {
  56 + widget.onUpdate(newValue);
  57 + }
  58 + setState(() {
  59 + value = newValue;
  60 + });
  61 + }
  62 +
  63 + @override
  64 + void dispose() {
  65 + super.dispose();
  66 + widget?.onDispose?.call();
  67 + if (value is ChangeNotifier) {
  68 + (value as ChangeNotifier)?.dispose();
  69 + } else if (value is StreamController) {
  70 + (value as StreamController)?.close();
  71 + }
  72 + value = null;
  73 + }
  74 +}
  75 +
5 // It's a experimental feature 76 // It's a experimental feature
6 class SimpleBuilder extends StatefulWidget { 77 class SimpleBuilder extends StatefulWidget {
7 final Widget Function(BuildContext) builder; 78 final Widget Function(BuildContext) builder;