Makes FlexibleSpaceBarSettings public (#23803)
* Makes FlexibleSpaceSettingsPublic and adds a test
This commit is contained in:
parent
f03b00706f
commit
a4a0ff9ab4
@ -75,6 +75,19 @@ class FlexibleSpaceBar extends StatefulWidget {
|
|||||||
/// to the [FlexibleSpaceBar].
|
/// to the [FlexibleSpaceBar].
|
||||||
///
|
///
|
||||||
/// Used by [Scaffold] and [SliverAppBar].
|
/// 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({
|
static Widget createSettings({
|
||||||
double toolbarOpacity,
|
double toolbarOpacity,
|
||||||
double minExtent,
|
double minExtent,
|
||||||
@ -83,7 +96,7 @@ class FlexibleSpaceBar extends StatefulWidget {
|
|||||||
@required Widget child,
|
@required Widget child,
|
||||||
}) {
|
}) {
|
||||||
assert(currentExtent != null);
|
assert(currentExtent != null);
|
||||||
return _FlexibleSpaceBarSettings(
|
return FlexibleSpaceBarSettings(
|
||||||
toolbarOpacity: toolbarOpacity ?? 1.0,
|
toolbarOpacity: toolbarOpacity ?? 1.0,
|
||||||
minExtent: minExtent ?? currentExtent,
|
minExtent: minExtent ?? currentExtent,
|
||||||
maxExtent: maxExtent ?? currentExtent,
|
maxExtent: maxExtent ?? currentExtent,
|
||||||
@ -125,7 +138,7 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
double _getCollapsePadding(double t, _FlexibleSpaceBarSettings settings) {
|
double _getCollapsePadding(double t, FlexibleSpaceBarSettings settings) {
|
||||||
switch (widget.collapseMode) {
|
switch (widget.collapseMode) {
|
||||||
case CollapseMode.pin:
|
case CollapseMode.pin:
|
||||||
return -(settings.maxExtent - settings.currentExtent);
|
return -(settings.maxExtent - settings.currentExtent);
|
||||||
@ -140,7 +153,7 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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().');
|
assert(settings != null, 'A FlexibleSpaceBar must be wrapped in the widget returned by FlexibleSpaceBar.createSettings().');
|
||||||
|
|
||||||
final List<Widget> children = <Widget>[];
|
final List<Widget> children = <Widget>[];
|
||||||
@ -221,23 +234,42 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FlexibleSpaceBarSettings extends InheritedWidget {
|
/// Provides sizing and opacity information to a [FlexibleSpaceBar].
|
||||||
const _FlexibleSpaceBarSettings({
|
///
|
||||||
|
/// 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,
|
Key key,
|
||||||
this.toolbarOpacity,
|
this.toolbarOpacity,
|
||||||
this.minExtent,
|
this.minExtent,
|
||||||
this.maxExtent,
|
this.maxExtent,
|
||||||
this.currentExtent,
|
@required this.currentExtent,
|
||||||
Widget child,
|
@required Widget child,
|
||||||
}) : super(key: key, child: child);
|
}) : assert(currentExtent != null),
|
||||||
|
super(key: key, child: child);
|
||||||
|
|
||||||
|
/// Affects how transparent the text within the toolbar appears.
|
||||||
final double toolbarOpacity;
|
final double toolbarOpacity;
|
||||||
|
|
||||||
|
/// Minimum height of the resulting [FlexibleSpaceBar] when fully collapsed.
|
||||||
final double minExtent;
|
final double minExtent;
|
||||||
|
|
||||||
|
/// Maximum height of the resulting [FlexibleSpaceBar] when fully expanded.
|
||||||
final double maxExtent;
|
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;
|
final double currentExtent;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool updateShouldNotify(_FlexibleSpaceBarSettings oldWidget) {
|
bool updateShouldNotify(FlexibleSpaceBarSettings oldWidget) {
|
||||||
return toolbarOpacity != oldWidget.toolbarOpacity
|
return toolbarOpacity != oldWidget.toolbarOpacity
|
||||||
|| minExtent != oldWidget.minExtent
|
|| minExtent != oldWidget.minExtent
|
||||||
|| maxExtent != oldWidget.maxExtent
|
|| maxExtent != oldWidget.maxExtent
|
||||||
|
@ -46,4 +46,95 @@ void main() {
|
|||||||
expect(center.dx, greaterThan(400.0 - size.width / 2.0));
|
expect(center.dx, greaterThan(400.0 - size.width / 2.0));
|
||||||
expect(center.dx, lessThan(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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user