Add expandedScale to FlexibleSpaceBar (#92160)

This commit is contained in:
Markus Aksli 2021-11-03 22:13:04 +00:00 committed by GitHub
parent f26aeda718
commit 9cfefafdeb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 1 deletions

View file

@ -82,7 +82,9 @@ class FlexibleSpaceBar extends StatefulWidget {
this.titlePadding,
this.collapseMode = CollapseMode.parallax,
this.stretchModes = const <StretchMode>[StretchMode.zoomBackground],
this.expandedTitleScale = 1.5,
}) : assert(collapseMode != null),
assert(expandedTitleScale >= 1),
super(key: key);
/// The primary contents of the flexible space bar when expanded.
@ -123,6 +125,14 @@ class FlexibleSpaceBar extends StatefulWidget {
/// not centered, `EdgeInsetsDirectional.only(start: 0, bottom: 16)` otherwise.
final EdgeInsetsGeometry? titlePadding;
/// Defines how much the title is scaled when the FlexibleSpaceBar is expanded
/// due to the user scrolling downwards. The title is scaled uniformly on the
/// x and y axes while maintaining its bottom-left position (bottom-center if
/// [centerTitle] is true).
///
/// Defaults to 1.5 and must be greater than 1.
final double expandedTitleScale;
/// Wraps a widget that contains an [AppBar] to convey sizing information down
/// to the [FlexibleSpaceBar].
///
@ -317,7 +327,7 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
start: effectiveCenterTitle ? 0.0 : 72.0,
bottom: 16.0,
);
final double scaleValue = Tween<double>(begin: 1.5, end: 1.0).transform(t);
final double scaleValue = Tween<double>(begin: widget.expandedTitleScale, end: 1.0).transform(t);
final Matrix4 scaleTransform = Matrix4.identity()
..scale(scaleValue, scaleValue, 1.0);
final Alignment titleAlignment = _getTitleAlignment(effectiveCenterTitle);

View file

@ -470,6 +470,78 @@ void main() {
);
});
testWidgets('FlexibleSpaceBar sets constraints for the title - override expandedTitleScale', (WidgetTester tester) async {
const double titleFontSize = 20.0;
const double height = 300.0;
const double expandedTitleScale = 3.0;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: height,
pinned: true,
stretch: true,
flexibleSpace: FlexibleSpaceBar(
expandedTitleScale: expandedTitleScale,
titlePadding: EdgeInsets.zero,
title: Text(
'X' * 41,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: titleFontSize,),
),
centerTitle: false,
),
),
SliverList(
delegate: SliverChildListDelegate(
<Widget>[
for (int i = 0; i < 3; i++)
SizedBox(
height: 200.0,
child: Center(child: Text('Item $i')),
),
],
),
),
],
),
),
),
);
// We drag up to fully collapse the space bar.
await tester.drag(find.text('Item 0'), const Offset(0, -600.0));
await tester.pumpAndSettle();
final Finder title = find.byType(Text).first;
final double collapsedWidth = tester.getRect(title).width;
// We drag down to fully expand the space bar.
await tester.drag(find.text('Item 2'), const Offset(0, 600.0));
await tester.pumpAndSettle();
// The title is shifted by this margin to maintain the position of the
// bottom edge.
const double bottomMargin = titleFontSize * (expandedTitleScale - 1);
// The title is scaled and transformed to be 3 times bigger, when the
// FlexibleSpaceBar is fully expanded, thus we expect the width to be
// 3 times smaller than the full width. The height of the text is the same
// as the font size, with 40 dps bottom margin to maintain its bottom position.
expect(
tester.getRect(title),
Rect.fromLTRB(
0,
height - titleFontSize - bottomMargin,
(collapsedWidth / 3).floorToDouble(),
height - bottomMargin,
),
);
});
testWidgets('FlexibleSpaceBar test titlePadding defaults', (WidgetTester tester) async {
Widget buildFrame(TargetPlatform platform, bool? centerTitle) {
return MaterialApp(