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
This commit is contained in:
Adam Barth 2015-11-03 14:14:19 -08:00
parent a0c8a4c61e
commit 78d35391ce
12 changed files with 41 additions and 42 deletions

View File

@ -108,7 +108,7 @@ class _ModalBottomSheetRoute extends ModalRoute {
}
Color get barrierColor => Colors.black54;
Widget createModalWidget() => new _BottomSheet(route: this);
Widget buildModalWidget(BuildContext context) => new _BottomSheet(route: this);
void didPop([dynamic result]) {
completer.complete(result);

View File

@ -125,7 +125,7 @@ class _DialogRoute extends ModalRoute {
Duration get transitionDuration => const Duration(milliseconds: 150);
Color get barrierColor => Colors.black54;
Widget createModalWidget() {
Widget buildModalWidget(BuildContext context) {
return new FadeTransition(
performance: performance,
opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.easeOut),

View File

@ -109,7 +109,9 @@ class _DrawerRoute extends TransitionRoute {
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]) {
assert(result == null); // because we don't do anything with it, so otherwise it'd be lost

View File

@ -138,10 +138,10 @@ class _MenuRoute extends TransitionRoute {
bool get opaque => false;
Duration get transitionDuration => _kMenuDuration;
List<Widget> createWidgets() => [
new ModalBarrier(),
new _DropdownMenu(route: this)
];
Widget _buildModalBarrier(BuildContext context) => new ModalBarrier();
Widget _buildDropDownMenu(BuildContext context) => new _DropdownMenu(route: this);
List<WidgetBuilder> get builders => <WidgetBuilder>[ _buildModalBarrier, _buildDropDownMenu ];
void didPop([dynamic result]) {
completer.complete(result);

View File

@ -114,7 +114,7 @@ class _MenuRoute extends ModalRoute {
bool get opaque => false;
Duration get transitionDuration => _kMenuDuration;
Widget createModalWidget() => new _PopupMenu(route: this);
Widget buildModalWidget(BuildContext context) => new _PopupMenu(route: this);
void didPop([dynamic result]) {
completer.complete(result);

View File

@ -89,13 +89,13 @@ class _DraggableState extends State<Draggable> {
}
);
_avatar.update(point);
_avatar.rebuild(context);
_avatar.markNeedsBuild(context);
}
void _updateDrag(PointerInputEvent event) {
if (_avatar != null) {
_avatar.update(new Point(event.x, event.y));
_avatar.rebuild(context);
_avatar.markNeedsBuild(context);
}
}
@ -223,12 +223,12 @@ class _DragAvatar {
_activeTargetWillAcceptDrop = _activeTarget != null && _activeTarget.didEnter(data);
}
void rebuild(BuildContext context) {
void markNeedsBuild(BuildContext context) {
if (_entry == null) {
_entry = new OverlayEntry(child: _build(context));
_entry = new OverlayEntry(builder: _build);
Navigator.of(context).overlay.insert(_entry);
} else {
_entry.child = _build(context);
_entry.markNeedsBuild();
}
}

View File

@ -72,7 +72,7 @@ class HeroController {
void _addHeroesToOverlay(Iterable<Widget> heroes, OverlayState overlay) {
for (Widget hero in heroes) {
OverlayEntry entry = new OverlayEntry(child: hero);
OverlayEntry entry = new OverlayEntry(builder: (_) => hero);
overlay.insert(entry);
_overlayEntries.add(entry);
}

View File

@ -111,15 +111,18 @@ class ModalPosition {
abstract class ModalRoute extends TransitionRoute {
ModalPosition get position => null;
Color get barrierColor => _kTransparent;
Widget createModalWidget();
Widget buildModalWidget(BuildContext context);
List<Widget> createWidgets() {
return [
new _AnimatedModalBarrier(
color: new AnimatedColorValue(_kTransparent, end: barrierColor, curve: Curves.ease),
performance: performance
),
new _ModalScope(route: this, child: createModalWidget()),
];
Widget _buildModalBarrier(BuildContext context) {
return new _AnimatedModalBarrier(
color: new AnimatedColorValue(_kTransparent, end: barrierColor, curve: Curves.ease),
performance: performance
);
}
Widget _buildModalScope(BuildContext context) {
return new _ModalScope(route: this, child: buildModalWidget(context));
}
List<WidgetBuilder> get builders => <WidgetBuilder>[ _buildModalBarrier, _buildModalScope ];
}

View File

@ -7,18 +7,11 @@ import 'framework.dart';
class OverlayEntry {
OverlayEntry({
Widget child,
this.builder,
bool opaque: false
}) : _child = child, _opaque = opaque;
}) : _opaque = opaque;
Widget get child => _child;
Widget _child;
void set child (Widget value) {
if (_child == value)
return;
_child = value;
_rebuild();
}
final WidgetBuilder builder;
bool get opaque => _opaque;
bool _opaque;
@ -26,7 +19,7 @@ class OverlayEntry {
if (_opaque == value)
return;
_opaque = value;
_rebuild();
markNeedsBuild();
}
OverlayState _state;
@ -37,7 +30,8 @@ class OverlayEntry {
_state = null;
}
void _rebuild() {
void markNeedsBuild() {
// TODO(ianh): find a way to make this not rebuild the entire overlay
_state?.setState(() {});
}
}
@ -85,7 +79,7 @@ class OverlayState extends State<Overlay> {
OverlayEntry entry = _entries[i];
backwardsChildren.add(new KeyedSubtree(
key: new ObjectKey(entry),
child: entry.child
child: entry.builder(context)
));
if (entry.opaque)
break;

View File

@ -105,7 +105,7 @@ class PageRoute extends ModalRoute {
String get name => settings.name;
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();

View File

@ -25,15 +25,14 @@ class StateRoute extends Route {
}
class OverlayRoute extends Route {
List<Widget> createWidgets() => const <Widget>[];
List<WidgetBuilder> get builders => const <WidgetBuilder>[];
List<OverlayEntry> get overlayEntries => _overlayEntries;
final List<OverlayEntry> _overlayEntries = new List<OverlayEntry>();
void didPush(OverlayState overlay, OverlayEntry insertionPoint) {
List<Widget> widgets = createWidgets();
for (Widget widget in widgets) {
_overlayEntries.add(new OverlayEntry(child: widget));
for (WidgetBuilder builder in builders) {
_overlayEntries.add(new OverlayEntry(builder: builder));
overlay?.insert(_overlayEntries.last, above: insertionPoint);
insertionPoint = _overlayEntries.last;
}

View File

@ -4,7 +4,8 @@ import 'package:test/test.dart';
import 'widget_tester.dart';
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) {