From f7aac40bc41c045de9139277e2b4ed28691596b3 Mon Sep 17 00:00:00 2001 From: Will Wykeham Date: Wed, 9 Jan 2019 17:31:33 +0000 Subject: [PATCH] Add onDidChange callback to StoreConnection --- lib/flutter_built_redux.dart | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/flutter_built_redux.dart b/lib/flutter_built_redux.dart index 09bb9b7..1d65cef 100644 --- a/lib/flutter_built_redux.dart +++ b/lib/flutter_built_redux.dart @@ -12,6 +12,12 @@ typedef LocalState Connect(StoreState state); typedef Widget StoreConnectionBuilder( BuildContext context, LocalState state, Actions actions); +/// [OnDidChange] is called on state change, after the build method +/// +/// This can be useful for running animations after build is complete, for +/// example scrolling to the end of a list when a new item is added. +typedef void OnDidChange(LocalState state); + /// [StoreConnection] is a widget that rebuilds when the redux store /// has triggered and the connect function yields a new result. It is an implementation /// of `StoreConnector` that takes a connect function and builder function as parameters @@ -26,6 +32,10 @@ typedef Widget StoreConnectionBuilder( /// [builder] is a function that takes a `BuildContext`, the `LocalState` returned from /// connect, and your `ReduxActions` class and returns a widget. /// +/// [onDidChange] is called on state change, after the build method. +/// This can be useful for running animations after build is complete, for +/// example scrolling to the end of a list when a new item is added. +/// /// [StoreState] is the generic type of your built_redux store's state object /// [Actions] is the generic tyoe of your built_redux store's actions contiainer /// [LocalState] is the state from your store that this widget needs to render. @@ -34,17 +44,20 @@ class StoreConnection extends StoreConnector { final Connect _connect; final StoreConnectionBuilder _builder; + final OnDidChange _onDidChange; StoreConnection({ @required LocalState connect(StoreState state), @required Widget builder(BuildContext context, LocalState state, Actions actions), Key key, + onDidChange(LocalState state), }) : assert(connect != null, 'StoreConnection: connect must not be null'), assert(builder != null, 'StoreConnection: builder must not be null'), _connect = connect, _builder = builder, + _onDidChange = onDidChange, super(key: key); @protected @@ -53,6 +66,14 @@ class StoreConnection @protected Widget build(BuildContext context, LocalState state, Actions actions) => _builder(context, state, actions); + + @protected + @override + onDidChange(LocalState state) { + if (_onDidChange != null) { + _onDidChange(state); + } + } } /// [StoreConnector] is a widget that rebuilds when the redux store @@ -79,6 +100,11 @@ abstract class StoreConnector @@ -128,8 +154,13 @@ class _StoreConnectorState _storeSub = _store .substateStream((state) => widget.connect(state as StoreState)) .listen((change) { + final newState = change.next; + WidgetsBinding.instance.addPostFrameCallback((_) { + widget.onDidChange(newState); + }); + setState(() { - _state = change.next; + _state = newState; }); }); }