Unverified Commit a4a0ff9a authored by jslavitz's avatar jslavitz Committed by GitHub

Makes FlexibleSpaceBarSettings public (#23803)

* Makes FlexibleSpaceSettingsPublic and adds a test
parent f03b0070
......@@ -75,6 +75,19 @@ class FlexibleSpaceBar extends StatefulWidget {
/// to the [FlexibleSpaceBar].
///
/// Used by [Scaffold] and [SliverAppBar].
///
/// `toolbarOpacity` affects how transparent the text within the toolbar
/// appears. `minExtent` sets the minimum height of the resulting
/// [FlexibleSpaceBar] when fully collapsed. `maxExtent` sets the maximum
/// height of the resulting [FlexibleSpaceBar] when fully expanded.
/// `currentExtent` sets the scale of the [FlexibleSpaceBar.background] and
/// [FlexibleSpaceBar.title] widgets of [FlexibleSpaceBar] upon
/// initialization.
///
/// See also:
///
/// * [FlexibleSpaceBarSettings] which creates a settings object that can be
/// used to specify these settings to a [FlexibleSpaceBar].
static Widget createSettings({
double toolbarOpacity,
double minExtent,
......@@ -83,7 +96,7 @@ class FlexibleSpaceBar extends StatefulWidget {
@required Widget child,
}) {
assert(currentExtent != null);
return _FlexibleSpaceBarSettings(
return FlexibleSpaceBarSettings(
toolbarOpacity: toolbarOpacity ?? 1.0,
minExtent: minExtent ?? currentExtent,
maxExtent: maxExtent ?? currentExtent,
......@@ -125,7 +138,7 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
return null;
}
double _getCollapsePadding(double t, _FlexibleSpaceBarSettings settings) {
double _getCollapsePadding(double t, FlexibleSpaceBarSettings settings) {
switch (widget.collapseMode) {
case CollapseMode.pin:
return -(settings.maxExtent - settings.currentExtent);
......@@ -140,7 +153,7 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
@override
Widget build(BuildContext context) {
final _FlexibleSpaceBarSettings settings = context.inheritFromWidgetOfExactType(_FlexibleSpaceBarSettings);
final FlexibleSpaceBarSettings settings = context.inheritFromWidgetOfExactType(FlexibleSpaceBarSettings);
assert(settings != null, 'A FlexibleSpaceBar must be wrapped in the widget returned by FlexibleSpaceBar.createSettings().');
final List<Widget> children = <Widget>[];
......@@ -221,23 +234,42 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
}
}
class _FlexibleSpaceBarSettings extends InheritedWidget {
const _FlexibleSpaceBarSettings({
/// Provides sizing and opacity information to a [FlexibleSpaceBar].
///
/// See also:
///
/// * [FlexibleSpaceBar] which creates a flexible space bar.
class FlexibleSpaceBarSettings extends InheritedWidget {
/// Creates a Flexible Space Bar Settings widget.
///
/// Used by [Scaffold] and [SliverAppBar]. [child] must have a
/// [FlexibleSpaceBar] widget in its tree for the settings to take affect.
const FlexibleSpaceBarSettings({
Key key,
this.toolbarOpacity,
this.minExtent,
this.maxExtent,
this.currentExtent,
Widget child,
}) : super(key: key, child: child);
@required this.currentExtent,
@required Widget child,
}) : assert(currentExtent != null),
super(key: key, child: child);
/// Affects how transparent the text within the toolbar appears.
final double toolbarOpacity;
/// Minimum height of the resulting [FlexibleSpaceBar] when fully collapsed.
final double minExtent;
/// Maximum height of the resulting [FlexibleSpaceBar] when fully expanded.
final double maxExtent;
/// If the [FlexibleSpaceBar.title] or the [FlexibleSpaceBar.background] is
/// not null, then this value is used to calculate the relative scale of
/// these elements upon initialization.
final double currentExtent;
@override
bool updateShouldNotify(_FlexibleSpaceBarSettings oldWidget) {
bool updateShouldNotify(FlexibleSpaceBarSettings oldWidget) {
return toolbarOpacity != oldWidget.toolbarOpacity
|| minExtent != oldWidget.minExtent
|| maxExtent != oldWidget.maxExtent
......
......@@ -46,4 +46,95 @@ void main() {
expect(center.dx, greaterThan(400.0 - size.width / 2.0));
expect(center.dx, lessThan(400.0 + size.width / 2.0));
});
testWidgets('FlexibleSpaceBarSettings provides settings to a FlexibleSpaceBar', (WidgetTester tester) async {
const double minExtent = 100.0;
const double initExtent = 200.0;
const double maxExtent = 300.0;
const double alpha = 0.5;
final FlexibleSpaceBarSettings customSettings = FlexibleSpaceBar.createSettings(
currentExtent: initExtent,
minExtent: minExtent,
maxExtent: maxExtent,
toolbarOpacity: alpha,
child: AppBar(
flexibleSpace: const FlexibleSpaceBar(
title: Text('title'),
background: Text('X2'),
collapseMode: CollapseMode.pin,
),
),
);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: CustomScrollView(
primary: true,
slivers: <Widget>[
SliverPersistentHeader(
floating: true,
pinned: true,
delegate: TestDelegate(settings: customSettings),
),
SliverToBoxAdapter(
child: Container(
height: 1200.0,
color: Colors.orange[400],
),
),
],
),
),
),
);
final RenderBox clipRect = tester.renderObject(find.byType(ClipRect).first);
final Transform transform = tester.firstWidget(find.byType(Transform));
// The current (200) is half way between the min (100) and max (300) and the
// lerp values used to calculate the scale are 1 and 1.5, so we check for 1.25.
expect(transform.transform.getMaxScaleOnAxis(), 1.25);
// The space bar rect always starts fully expanded.
expect(clipRect.size.height, maxExtent);
final Element actionTextBox = tester.element(find.text('title'));
final Text textWidget = actionTextBox.widget;
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(actionTextBox);
TextStyle effectiveStyle = textWidget.style;
effectiveStyle = defaultTextStyle.style.merge(textWidget.style);
expect(effectiveStyle.color.alpha, 128); // Which is alpha of .5
// We drag up to fully collapse the space bar.
await tester.drag(find.byType(Container).first, const Offset(0, -400.0));
await tester.pumpAndSettle();
expect(clipRect.size.height, minExtent);
});
}
class TestDelegate extends SliverPersistentHeaderDelegate {
const TestDelegate({
this.settings,
});
final FlexibleSpaceBarSettings settings;
@override
double get maxExtent => settings.maxExtent;
@override
double get minExtent => settings.minExtent;
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return settings;
}
@override
bool shouldRebuild(TestDelegate oldDelegate) => false;
}
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