diff --git a/packages/flutter/lib/src/material/drawer.dart b/packages/flutter/lib/src/material/drawer.dart index d3f2480358..5661a8d93d 100644 --- a/packages/flutter/lib/src/material/drawer.dart +++ b/packages/flutter/lib/src/material/drawer.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/scheduler.dart'; import 'package:flutter/widgets.dart'; import 'colors.dart'; @@ -81,7 +82,7 @@ class DrawerControllerState extends State { LocalHistoryEntry _historyEntry; // TODO(abarth): This should be a GlobalValueKey when those exist. - GlobalKey get _focusKey => new GlobalObjectKey(config.key); + GlobalKey get _drawerKey => new GlobalObjectKey(config.key); void _ensureHistoryEntry() { if (_historyEntry == null) { @@ -89,7 +90,7 @@ class DrawerControllerState extends State { if (route != null) { _historyEntry = new LocalHistoryEntry(onRemove: _handleHistoryEntryRemoved); route.addLocalHistoryEntry(_historyEntry); - Focus.moveScopeTo(_focusKey, context: context); + Focus.moveScopeTo(_drawerKey, context: context); } } } @@ -116,19 +117,20 @@ class DrawerControllerState extends State { } AnimationController _controller; - double _width = _kEdgeDragWidth; - - void _handleSizeChanged(Size newSize) { - setState(() { - _width = newSize.width; - }); - } void _handleTapDown(Point position) { _controller.stop(); _ensureHistoryEntry(); } + double get _width { + assert(!Scheduler.debugInFrame); // we should never try to read the tree state while building or laying out + RenderBox drawerBox = _drawerKey.currentContext?.findRenderObject(); + if (drawerBox != null) + return drawerBox.size.width; + return _kWidth; // drawer not being shown currently + } + void _move(double delta) { _controller.value += delta / _width; } @@ -193,13 +195,10 @@ class DrawerControllerState extends State { child: new Align( alignment: const FractionalOffset(1.0, 0.5), widthFactor: _controller.value, - child: new SizeObserver( - onSizeChanged: _handleSizeChanged, - child: new RepaintBoundary( - child: new Focus( - key: _focusKey, - child: config.child - ) + child: new RepaintBoundary( + child: new Focus( + key: _drawerKey, + child: config.child ) ) ) diff --git a/packages/flutter/lib/src/scheduler/scheduler.dart b/packages/flutter/lib/src/scheduler/scheduler.dart index 22387c4167..780350321a 100644 --- a/packages/flutter/lib/src/scheduler/scheduler.dart +++ b/packages/flutter/lib/src/scheduler/scheduler.dart @@ -215,11 +215,12 @@ abstract class Scheduler extends BindingBase { _postFrameCallbacks.add(callback); } - bool _isInFrame = false; + static bool get debugInFrame => _debugInFrame; + static bool _debugInFrame = false; void _invokeTransientFrameCallbacks(Duration timeStamp) { Timeline.startSync('Animate'); - assert(_isInFrame); + assert(_debugInFrame); Map callbacks = _transientCallbacks; _transientCallbacks = new Map(); callbacks.forEach((int id, FrameCallback callback) { @@ -239,8 +240,8 @@ abstract class Scheduler extends BindingBase { /// [addPostFrameCallback]. void handleBeginFrame(Duration rawTimeStamp) { Timeline.startSync('Begin frame'); - assert(!_isInFrame); - _isInFrame = true; + assert(!_debugInFrame); + assert(() { _debugInFrame = true; return true; }); Duration timeStamp = new Duration( microseconds: (rawTimeStamp.inMicroseconds / timeDilation).round()); _hasRequestedABeginFrameCallback = false; @@ -255,7 +256,7 @@ abstract class Scheduler extends BindingBase { for (FrameCallback callback in localPostFrameCallbacks) invokeFrameCallback(callback, timeStamp); - _isInFrame = false; + assert(() { _debugInFrame = false; return true; }); Timeline.finishSync(); // All frame-related callbacks have been executed. Run lower-priority tasks.