Unverified Commit 9bc3bc98 authored by amirh's avatar amirh Committed by GitHub

expose scaled fab area in ScaffoldGeometry (#14683)

parent a11da238
...@@ -37,9 +37,6 @@ enum _ScaffoldSlot { ...@@ -37,9 +37,6 @@ enum _ScaffoldSlot {
statusBar, statusBar,
} }
// Examples can assume:
// ScaffoldGeometry scaffoldGeometry;
/// Geometry information for scaffold components. /// Geometry information for scaffold components.
/// ///
/// To get a [ValueNotifier] for the scaffold geometry call /// To get a [ValueNotifier] for the scaffold geometry call
...@@ -49,7 +46,6 @@ class ScaffoldGeometry { ...@@ -49,7 +46,6 @@ class ScaffoldGeometry {
const ScaffoldGeometry({ const ScaffoldGeometry({
this.bottomNavigationBarTop, this.bottomNavigationBarTop,
this.floatingActionButtonArea, this.floatingActionButtonArea,
this.floatingActionButtonScale: 1.0,
}); });
/// The distance from the scaffold's top edge to the top edge of the /// The distance from the scaffold's top edge to the top edge of the
...@@ -62,38 +58,35 @@ class ScaffoldGeometry { ...@@ -62,38 +58,35 @@ class ScaffoldGeometry {
/// The rectangle in which the scaffold is laying out /// The rectangle in which the scaffold is laying out
/// [Scaffold.floatingActionButton]. /// [Scaffold.floatingActionButton].
/// ///
/// The floating action button might be scaled inside this rectangle, to get
/// the bounding rectangle in which the floating action is painted scale this
/// value by [floatingActionButtonScale].
///
/// ## Sample code
///
/// ```dart
/// final Rect scaledFab = Rect.lerp(
/// scaffoldGeometry.floatingActionButtonArea.center & Size.zero,
/// scaffoldGeometry.floatingActionButtonArea,
/// scaffoldGeometry.floatingActionButtonScale
/// );
/// ```
///
/// This is null when there is no floating action button showing. /// This is null when there is no floating action button showing.
final Rect floatingActionButtonArea; final Rect floatingActionButtonArea;
/// The amount by which the [Scaffold.floatingActionButton] is scaled. ScaffoldGeometry _scaleFab(double scaleFactor) {
/// if (scaleFactor == 1.0)
/// To get the bounding rectangle in which the floating action button is return this;
/// painted scaled [floatingActionPosition] by this proportion.
/// if (scaleFactor == 0.0)
/// This will be 0 when there is no [Scaffold.floatingActionButton] set. return new ScaffoldGeometry(bottomNavigationBarTop: bottomNavigationBarTop);
final double floatingActionButtonScale;
final Rect scaledFab = Rect.lerp(
floatingActionButtonArea.center & Size.zero,
floatingActionButtonArea,
scaleFactor
);
return new ScaffoldGeometry(
bottomNavigationBarTop: bottomNavigationBarTop,
floatingActionButtonArea: scaledFab,
);
}
} }
class _ScaffoldGeometryNotifier extends ValueNotifier<ScaffoldGeometry> { class _ScaffoldGeometryNotifier extends ChangeNotifier implements ValueListenable<ScaffoldGeometry> {
_ScaffoldGeometryNotifier(ScaffoldGeometry geometry, this.context) _ScaffoldGeometryNotifier(this.geometry, this.context)
: assert (context != null), : assert (context != null);
super(geometry);
final BuildContext context; final BuildContext context;
double fabScale;
ScaffoldGeometry geometry;
@override @override
ScaffoldGeometry get value { ScaffoldGeometry get value {
...@@ -107,7 +100,7 @@ class _ScaffoldGeometryNotifier extends ValueNotifier<ScaffoldGeometry> { ...@@ -107,7 +100,7 @@ class _ScaffoldGeometryNotifier extends ValueNotifier<ScaffoldGeometry> {
); );
return true; return true;
}()); }());
return super.value; return geometry._scaleFab(fabScale);
} }
void _updateWith({ void _updateWith({
...@@ -115,16 +108,12 @@ class _ScaffoldGeometryNotifier extends ValueNotifier<ScaffoldGeometry> { ...@@ -115,16 +108,12 @@ class _ScaffoldGeometryNotifier extends ValueNotifier<ScaffoldGeometry> {
Rect floatingActionButtonArea, Rect floatingActionButtonArea,
double floatingActionButtonScale, double floatingActionButtonScale,
}) { }) {
final double newFloatingActionButtonScale = floatingActionButtonScale ?? super.value?.floatingActionButtonScale; fabScale = floatingActionButtonScale ?? fabScale;
Rect newFloatingActionButtonArea; geometry = new ScaffoldGeometry(
if (newFloatingActionButtonScale != 0.0) bottomNavigationBarTop: bottomNavigationBarTop ?? geometry?.bottomNavigationBarTop,
newFloatingActionButtonArea = floatingActionButtonArea ?? super.value?.floatingActionButtonArea; floatingActionButtonArea: floatingActionButtonArea ?? geometry?.floatingActionButtonArea,
value = new ScaffoldGeometry(
bottomNavigationBarTop: bottomNavigationBarTop ?? super.value?.bottomNavigationBarTop,
floatingActionButtonArea: newFloatingActionButtonArea,
floatingActionButtonScale: newFloatingActionButtonScale,
); );
notifyListeners();
} }
} }
......
...@@ -832,10 +832,6 @@ void main() { ...@@ -832,10 +832,6 @@ void main() {
geometry.floatingActionButtonArea, geometry.floatingActionButtonArea,
fabRect fabRect
); );
expect(
geometry.floatingActionButtonScale,
1.0
);
}); });
testWidgets('no floatingActionButton', (WidgetTester tester) async { testWidgets('no floatingActionButton', (WidgetTester tester) async {
...@@ -849,11 +845,6 @@ void main() { ...@@ -849,11 +845,6 @@ void main() {
final GeometryListenerState listenerState = tester.state(find.byType(GeometryListener)); final GeometryListenerState listenerState = tester.state(find.byType(GeometryListener));
final ScaffoldGeometry geometry = listenerState.cache.value; final ScaffoldGeometry geometry = listenerState.cache.value;
expect(
geometry.floatingActionButtonScale,
0.0
);
expect( expect(
geometry.floatingActionButtonArea, geometry.floatingActionButtonArea,
null null
...@@ -878,18 +869,77 @@ void main() { ...@@ -878,18 +869,77 @@ void main() {
), ),
))); )));
final GeometryListenerState listenerState = tester.state(find.byType(GeometryListener));
await tester.pump(const Duration(milliseconds: 50)); await tester.pump(const Duration(milliseconds: 50));
final GeometryListenerState listenerState = tester.state(find.byType(GeometryListener)); ScaffoldGeometry geometry = listenerState.cache.value;
final ScaffoldGeometry geometry = listenerState.cache.value;
final Rect transitioningFabRect = geometry.floatingActionButtonArea;
await tester.pump(const Duration(seconds: 3));
geometry = listenerState.cache.value;
final RenderBox floatingActionButtonBox = tester.renderObject(find.byKey(key));
final Rect fabRect = floatingActionButtonBox.localToGlobal(Offset.zero) & floatingActionButtonBox.size;
expect(
geometry.floatingActionButtonArea,
fabRect
);
expect(
geometry.floatingActionButtonArea.center,
transitioningFabRect.center
);
expect( expect(
geometry.floatingActionButtonScale, geometry.floatingActionButtonArea.width,
inExclusiveRange(0.0, 1.0), greaterThan(transitioningFabRect.width)
);
expect(
geometry.floatingActionButtonArea.height,
greaterThan(transitioningFabRect.height)
); );
}); });
});
testWidgets('change notifications', (WidgetTester tester) async {
final GlobalKey key = new GlobalKey();
int numNotificationsAtLastFrame = 0;
await tester.pumpWidget(new MaterialApp(home: new Scaffold(
body: new ConstrainedBox(
constraints: const BoxConstraints.expand(height: 80.0),
child: new GeometryListener(),
),
)));
final GeometryListenerState listenerState = tester.state(find.byType(GeometryListener));
expect(listenerState.numNotifications, greaterThan(numNotificationsAtLastFrame));
numNotificationsAtLastFrame = listenerState.numNotifications;
await tester.pumpWidget(new MaterialApp(home: new Scaffold(
body: new Container(),
floatingActionButton: new FloatingActionButton(
key: key,
child: new GeometryListener(),
onPressed: () {},
),
)));
expect(listenerState.numNotifications, greaterThan(numNotificationsAtLastFrame));
numNotificationsAtLastFrame = listenerState.numNotifications;
await tester.pump(const Duration(milliseconds: 50));
expect(listenerState.numNotifications, greaterThan(numNotificationsAtLastFrame));
numNotificationsAtLastFrame = listenerState.numNotifications;
await tester.pump(const Duration(seconds: 3));
expect(listenerState.numNotifications, greaterThan(numNotificationsAtLastFrame));
numNotificationsAtLastFrame = listenerState.numNotifications;
});
});
} }
class GeometryListener extends StatefulWidget { class GeometryListener extends StatefulWidget {
......
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