Commit 78d35391 authored by Adam Barth's avatar Adam Barth

Stocks list doesn't update when stocks are loaded

Previously, we passed widgets up the hierarchy to display them in the overlay,
but that breaks the change propagation logic because those widgets won't get
rebuilt.  Now we pass WidgetBuilders instead, which can be rebuilt when the
overlay rebuilds.

Fixes #1913
parent a0c8a4c6
...@@ -108,7 +108,7 @@ class _ModalBottomSheetRoute extends ModalRoute { ...@@ -108,7 +108,7 @@ class _ModalBottomSheetRoute extends ModalRoute {
} }
Color get barrierColor => Colors.black54; Color get barrierColor => Colors.black54;
Widget createModalWidget() => new _BottomSheet(route: this); Widget buildModalWidget(BuildContext context) => new _BottomSheet(route: this);
void didPop([dynamic result]) { void didPop([dynamic result]) {
completer.complete(result); completer.complete(result);
......
...@@ -125,7 +125,7 @@ class _DialogRoute extends ModalRoute { ...@@ -125,7 +125,7 @@ class _DialogRoute extends ModalRoute {
Duration get transitionDuration => const Duration(milliseconds: 150); Duration get transitionDuration => const Duration(milliseconds: 150);
Color get barrierColor => Colors.black54; Color get barrierColor => Colors.black54;
Widget createModalWidget() { Widget buildModalWidget(BuildContext context) {
return new FadeTransition( return new FadeTransition(
performance: performance, performance: performance,
opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.easeOut), opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.easeOut),
......
...@@ -109,7 +109,9 @@ class _DrawerRoute extends TransitionRoute { ...@@ -109,7 +109,9 @@ class _DrawerRoute extends TransitionRoute {
return _performance; return _performance;
} }
List<Widget> createWidgets() => [ new _Drawer(route: this) ]; List<WidgetBuilder> get builders => <WidgetBuilder>[ _build ];
Widget _build(BuildContext context) => new _Drawer(route: this);
void didPop([dynamic result]) { void didPop([dynamic result]) {
assert(result == null); // because we don't do anything with it, so otherwise it'd be lost assert(result == null); // because we don't do anything with it, so otherwise it'd be lost
......
...@@ -138,10 +138,10 @@ class _MenuRoute extends TransitionRoute { ...@@ -138,10 +138,10 @@ class _MenuRoute extends TransitionRoute {
bool get opaque => false; bool get opaque => false;
Duration get transitionDuration => _kMenuDuration; Duration get transitionDuration => _kMenuDuration;
List<Widget> createWidgets() => [ Widget _buildModalBarrier(BuildContext context) => new ModalBarrier();
new ModalBarrier(), Widget _buildDropDownMenu(BuildContext context) => new _DropdownMenu(route: this);
new _DropdownMenu(route: this)
]; List<WidgetBuilder> get builders => <WidgetBuilder>[ _buildModalBarrier, _buildDropDownMenu ];
void didPop([dynamic result]) { void didPop([dynamic result]) {
completer.complete(result); completer.complete(result);
......
...@@ -114,7 +114,7 @@ class _MenuRoute extends ModalRoute { ...@@ -114,7 +114,7 @@ class _MenuRoute extends ModalRoute {
bool get opaque => false; bool get opaque => false;
Duration get transitionDuration => _kMenuDuration; Duration get transitionDuration => _kMenuDuration;
Widget createModalWidget() => new _PopupMenu(route: this); Widget buildModalWidget(BuildContext context) => new _PopupMenu(route: this);
void didPop([dynamic result]) { void didPop([dynamic result]) {
completer.complete(result); completer.complete(result);
......
...@@ -89,13 +89,13 @@ class _DraggableState extends State<Draggable> { ...@@ -89,13 +89,13 @@ class _DraggableState extends State<Draggable> {
} }
); );
_avatar.update(point); _avatar.update(point);
_avatar.rebuild(context); _avatar.markNeedsBuild(context);
} }
void _updateDrag(PointerInputEvent event) { void _updateDrag(PointerInputEvent event) {
if (_avatar != null) { if (_avatar != null) {
_avatar.update(new Point(event.x, event.y)); _avatar.update(new Point(event.x, event.y));
_avatar.rebuild(context); _avatar.markNeedsBuild(context);
} }
} }
...@@ -223,12 +223,12 @@ class _DragAvatar { ...@@ -223,12 +223,12 @@ class _DragAvatar {
_activeTargetWillAcceptDrop = _activeTarget != null && _activeTarget.didEnter(data); _activeTargetWillAcceptDrop = _activeTarget != null && _activeTarget.didEnter(data);
} }
void rebuild(BuildContext context) { void markNeedsBuild(BuildContext context) {
if (_entry == null) { if (_entry == null) {
_entry = new OverlayEntry(child: _build(context)); _entry = new OverlayEntry(builder: _build);
Navigator.of(context).overlay.insert(_entry); Navigator.of(context).overlay.insert(_entry);
} else { } else {
_entry.child = _build(context); _entry.markNeedsBuild();
} }
} }
......
...@@ -72,7 +72,7 @@ class HeroController { ...@@ -72,7 +72,7 @@ class HeroController {
void _addHeroesToOverlay(Iterable<Widget> heroes, OverlayState overlay) { void _addHeroesToOverlay(Iterable<Widget> heroes, OverlayState overlay) {
for (Widget hero in heroes) { for (Widget hero in heroes) {
OverlayEntry entry = new OverlayEntry(child: hero); OverlayEntry entry = new OverlayEntry(builder: (_) => hero);
overlay.insert(entry); overlay.insert(entry);
_overlayEntries.add(entry); _overlayEntries.add(entry);
} }
......
...@@ -111,15 +111,18 @@ class ModalPosition { ...@@ -111,15 +111,18 @@ class ModalPosition {
abstract class ModalRoute extends TransitionRoute { abstract class ModalRoute extends TransitionRoute {
ModalPosition get position => null; ModalPosition get position => null;
Color get barrierColor => _kTransparent; Color get barrierColor => _kTransparent;
Widget createModalWidget(); Widget buildModalWidget(BuildContext context);
List<Widget> createWidgets() { Widget _buildModalBarrier(BuildContext context) {
return [ return new _AnimatedModalBarrier(
new _AnimatedModalBarrier( color: new AnimatedColorValue(_kTransparent, end: barrierColor, curve: Curves.ease),
color: new AnimatedColorValue(_kTransparent, end: barrierColor, curve: Curves.ease), performance: performance
performance: performance );
),
new _ModalScope(route: this, child: createModalWidget()),
];
} }
Widget _buildModalScope(BuildContext context) {
return new _ModalScope(route: this, child: buildModalWidget(context));
}
List<WidgetBuilder> get builders => <WidgetBuilder>[ _buildModalBarrier, _buildModalScope ];
} }
...@@ -7,18 +7,11 @@ import 'framework.dart'; ...@@ -7,18 +7,11 @@ import 'framework.dart';
class OverlayEntry { class OverlayEntry {
OverlayEntry({ OverlayEntry({
Widget child, this.builder,
bool opaque: false bool opaque: false
}) : _child = child, _opaque = opaque; }) : _opaque = opaque;
Widget get child => _child; final WidgetBuilder builder;
Widget _child;
void set child (Widget value) {
if (_child == value)
return;
_child = value;
_rebuild();
}
bool get opaque => _opaque; bool get opaque => _opaque;
bool _opaque; bool _opaque;
...@@ -26,7 +19,7 @@ class OverlayEntry { ...@@ -26,7 +19,7 @@ class OverlayEntry {
if (_opaque == value) if (_opaque == value)
return; return;
_opaque = value; _opaque = value;
_rebuild(); markNeedsBuild();
} }
OverlayState _state; OverlayState _state;
...@@ -37,7 +30,8 @@ class OverlayEntry { ...@@ -37,7 +30,8 @@ class OverlayEntry {
_state = null; _state = null;
} }
void _rebuild() { void markNeedsBuild() {
// TODO(ianh): find a way to make this not rebuild the entire overlay
_state?.setState(() {}); _state?.setState(() {});
} }
} }
...@@ -85,7 +79,7 @@ class OverlayState extends State<Overlay> { ...@@ -85,7 +79,7 @@ class OverlayState extends State<Overlay> {
OverlayEntry entry = _entries[i]; OverlayEntry entry = _entries[i];
backwardsChildren.add(new KeyedSubtree( backwardsChildren.add(new KeyedSubtree(
key: new ObjectKey(entry), key: new ObjectKey(entry),
child: entry.child child: entry.builder(context)
)); ));
if (entry.opaque) if (entry.opaque)
break; break;
......
...@@ -105,7 +105,7 @@ class PageRoute extends ModalRoute { ...@@ -105,7 +105,7 @@ class PageRoute extends ModalRoute {
String get name => settings.name; String get name => settings.name;
Duration get transitionDuration => const Duration(milliseconds: 150); Duration get transitionDuration => const Duration(milliseconds: 150);
Widget createModalWidget() => new _Page(key: pageKey, route: this); Widget buildModalWidget(BuildContext context) => new _Page(key: pageKey, route: this);
final PageStorageBucket _storageBucket = new PageStorageBucket(); final PageStorageBucket _storageBucket = new PageStorageBucket();
......
...@@ -25,15 +25,14 @@ class StateRoute extends Route { ...@@ -25,15 +25,14 @@ class StateRoute extends Route {
} }
class OverlayRoute extends Route { class OverlayRoute extends Route {
List<Widget> createWidgets() => const <Widget>[]; List<WidgetBuilder> get builders => const <WidgetBuilder>[];
List<OverlayEntry> get overlayEntries => _overlayEntries; List<OverlayEntry> get overlayEntries => _overlayEntries;
final List<OverlayEntry> _overlayEntries = new List<OverlayEntry>(); final List<OverlayEntry> _overlayEntries = new List<OverlayEntry>();
void didPush(OverlayState overlay, OverlayEntry insertionPoint) { void didPush(OverlayState overlay, OverlayEntry insertionPoint) {
List<Widget> widgets = createWidgets(); for (WidgetBuilder builder in builders) {
for (Widget widget in widgets) { _overlayEntries.add(new OverlayEntry(builder: builder));
_overlayEntries.add(new OverlayEntry(child: widget));
overlay?.insert(_overlayEntries.last, above: insertionPoint); overlay?.insert(_overlayEntries.last, above: insertionPoint);
insertionPoint = _overlayEntries.last; insertionPoint = _overlayEntries.last;
} }
......
...@@ -4,7 +4,8 @@ import 'package:test/test.dart'; ...@@ -4,7 +4,8 @@ import 'package:test/test.dart';
import 'widget_tester.dart'; import 'widget_tester.dart';
class TestOverlayRoute extends OverlayRoute { class TestOverlayRoute extends OverlayRoute {
List<Widget> createWidgets() => <Widget>[ new Text('Overlay') ]; List<WidgetBuilder> get builders => <WidgetBuilder>[ _build ];
Widget _build(BuildContext context) => new Text('Overlay');
} }
bool _isOnStage(Element element) { bool _isOnStage(Element element) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment