Commit 629255eb authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Fix SizeChangedLayoutNotifier and its test. (#7361)

Previously, SizeChangedLayoutNotifier fired a notification even for
the first layout.

Also, previously its test relied on that, and didn't actually change
size at all. This fixes the test as well.

Also, rename SizeChangedLayoutNotificaion to SizeChangedLayoutNotification.
parent 86ad51f1
...@@ -9,17 +9,21 @@ import 'package:flutter/widgets.dart'; ...@@ -9,17 +9,21 @@ import 'package:flutter/widgets.dart';
/// this notification has changed, and that therefore any assumptions about that /// this notification has changed, and that therefore any assumptions about that
/// layout are no longer valid. /// layout are no longer valid.
/// ///
/// See [LayoutChangedNotification]. /// See [LayoutChangedNotification] for additional discussion of layout
class SizeChangedLayoutNotificaion extends LayoutChangedNotification {} /// notifications such as this one.
class SizeChangedLayoutNotification extends LayoutChangedNotification { }
/// A widget that automatically dispatches a [SizeChangedLayoutNotifier] when /// A widget that automatically dispatches a [SizeChangedLayoutNotifier] when
/// the layout of its child changes. /// the layout of its child changes.
/// ///
/// Useful especially when having some complex, layout-changing animation within /// Useful especially when having some complex, layout-changing animation within
/// [Material] that is also interactive. /// [Material] that is also interactive.
///
/// The notification is not sent for the initial layout (since the size doesn't
/// change in that case, it's just established).
class SizeChangedLayoutNotifier extends SingleChildRenderObjectWidget { class SizeChangedLayoutNotifier extends SingleChildRenderObjectWidget {
/// Creates a [SizeChangedLayoutNotifier] that dispatches layout changed /// Creates a [SizeChangedLayoutNotifier] that dispatches layout changed
/// notifications when [child] changes layout. /// notifications when [child] changes layout size.
SizeChangedLayoutNotifier({ SizeChangedLayoutNotifier({
Key key, Key key,
Widget child Widget child
...@@ -29,7 +33,7 @@ class SizeChangedLayoutNotifier extends SingleChildRenderObjectWidget { ...@@ -29,7 +33,7 @@ class SizeChangedLayoutNotifier extends SingleChildRenderObjectWidget {
_RenderSizeChangedWithCallback createRenderObject(BuildContext context) { _RenderSizeChangedWithCallback createRenderObject(BuildContext context) {
return new _RenderSizeChangedWithCallback( return new _RenderSizeChangedWithCallback(
onLayoutChangedCallback: () { onLayoutChangedCallback: () {
new SizeChangedLayoutNotificaion().dispatch(context); new SizeChangedLayoutNotification().dispatch(context);
} }
); );
} }
...@@ -39,15 +43,23 @@ class _RenderSizeChangedWithCallback extends RenderProxyBox { ...@@ -39,15 +43,23 @@ class _RenderSizeChangedWithCallback extends RenderProxyBox {
_RenderSizeChangedWithCallback({ _RenderSizeChangedWithCallback({
RenderBox child, RenderBox child,
this.onLayoutChangedCallback this.onLayoutChangedCallback
}) : super(child); }) : super(child) {
assert(onLayoutChangedCallback != null);
}
// There's a 1:1 relationship between the _RenderSizeChangedWithCallback and
// the `context` that is captured by the closure created by createRenderObject
// above to assign to onLayoutChangedCallback, and thus we know that the
// onLayoutChangedCallback will never change nor need to change.
final VoidCallback onLayoutChangedCallback;
VoidCallback onLayoutChangedCallback;
Size _oldSize; Size _oldSize;
@override @override
void performLayout() { void performLayout() {
super.performLayout(); super.performLayout();
if (onLayoutChangedCallback != null && size != _oldSize) if (_oldSize != null && size != _oldSize)
onLayoutChangedCallback(); onLayoutChangedCallback();
_oldSize = size; _oldSize = size;
} }
......
...@@ -18,33 +18,37 @@ void main() { ...@@ -18,33 +18,37 @@ void main() {
bool notified = false; bool notified = false;
await tester.pumpWidget( await tester.pumpWidget(
new NotificationListener<LayoutChangedNotification>( new Center(
child: new NotificationListener<LayoutChangedNotification>(
onNotification: (LayoutChangedNotification notification) { onNotification: (LayoutChangedNotification notification) {
notified = true; throw new Exception('Should not reach this point.');
return true;
}, },
child: new SizeChangedLayoutNotifier( child: new SizeChangedLayoutNotifier(
child: const SizedBox( child: const SizedBox(
width: 100.0, width: 100.0,
height: 100.0 height: 100.0,
) ),
) ),
) ),
),
); );
await tester.pumpWidget( await tester.pumpWidget(
new NotificationListener<LayoutChangedNotification>( new Center(
child: new NotificationListener<LayoutChangedNotification>(
onNotification: (LayoutChangedNotification notification) { onNotification: (LayoutChangedNotification notification) {
expect(notification, new isInstanceOf<SizeChangedLayoutNotification>());
notified = true; notified = true;
return true; return true;
}, },
child: new SizeChangedLayoutNotifier( child: new SizeChangedLayoutNotifier(
child: const SizedBox( child: const SizedBox(
width: 200.0, width: 200.0,
height: 100.0 height: 100.0,
) ),
) ),
) ),
),
); );
expect(notified, isTrue); expect(notified, isTrue);
......
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