Added LayoutChangedNotifier. (#5304)
Added a simple widget that automatically dispatches a LayoutChangedNotification when its child changes layout.
This commit is contained in:
parent
fd119f4f59
commit
de448c20e6
@ -656,5 +656,4 @@ class _InkHighlight extends InkFeature implements InkHighlight {
|
||||
_paintHighlight(canvas, rect.shift(originOffset), paint);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
/// Indicates that the size of one of the descendants of the object receiving
|
||||
/// this notification has changed, and that therefore any assumptions about that
|
||||
/// layout are no longer valid.
|
||||
///
|
||||
/// See [LayoutChangedNotification].
|
||||
class SizeChangedLayoutNotificaion extends LayoutChangedNotification {}
|
||||
|
||||
/// A widget that automatically dispatches a [SizeChangedLayoutNotifier] when
|
||||
/// the layout of its child changes.
|
||||
///
|
||||
/// Useful especially when having some complex, layout-changing animation within
|
||||
/// [Material] that is also interactive.
|
||||
class SizeChangedLayoutNotifier extends SingleChildRenderObjectWidget {
|
||||
/// Creates a [SizeChangedLayoutNotifier] that dispatches layout changed
|
||||
/// notifications when [child] changes layout.
|
||||
SizeChangedLayoutNotifier({
|
||||
Key key,
|
||||
Widget child
|
||||
}) : super(key: key, child: child);
|
||||
|
||||
@override
|
||||
_RenderSizeChangedWithCallback createRenderObject(BuildContext context) {
|
||||
return new _RenderSizeChangedWithCallback(
|
||||
onLayoutChangedCallback: () {
|
||||
new SizeChangedLayoutNotificaion().dispatch(context);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _RenderSizeChangedWithCallback extends RenderProxyBox {
|
||||
_RenderSizeChangedWithCallback({
|
||||
RenderBox child,
|
||||
this.onLayoutChangedCallback
|
||||
}) : super(child);
|
||||
|
||||
VoidCallback onLayoutChangedCallback;
|
||||
Size _oldSize;
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
super.performLayout();
|
||||
if (onLayoutChangedCallback != null && size != _oldSize)
|
||||
onLayoutChangedCallback();
|
||||
_oldSize = size;
|
||||
}
|
||||
}
|
@ -50,6 +50,7 @@ export 'src/widgets/scrollable_grid.dart';
|
||||
export 'src/widgets/scrollable_list.dart';
|
||||
export 'src/widgets/scrollable.dart';
|
||||
export 'src/widgets/semantics_debugger.dart';
|
||||
export 'src/widgets/size_changed_layout_notifier.dart';
|
||||
export 'src/widgets/status_transitions.dart';
|
||||
export 'src/widgets/table.dart';
|
||||
export 'src/widgets/text_selection.dart';
|
||||
|
@ -0,0 +1,52 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
class NotifyMaterial extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
new LayoutChangedNotification().dispatch(context);
|
||||
return new Container();
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('SizeChangedLayoutNotification test', (WidgetTester tester) async {
|
||||
bool notified = false;
|
||||
|
||||
await tester.pumpWidget(
|
||||
new NotificationListener<LayoutChangedNotification>(
|
||||
onNotification: (LayoutChangedNotification notification) {
|
||||
notified = true;
|
||||
return true;
|
||||
},
|
||||
child: new SizeChangedLayoutNotifier(
|
||||
child: new SizedBox(
|
||||
width: 100.0,
|
||||
height: 100.0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
new NotificationListener<LayoutChangedNotification>(
|
||||
onNotification: (LayoutChangedNotification notification) {
|
||||
notified = true;
|
||||
return true;
|
||||
},
|
||||
child: new SizeChangedLayoutNotifier(
|
||||
child: new SizedBox(
|
||||
width: 200.0,
|
||||
height: 100.0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
expect(notified, isTrue);
|
||||
});
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user