Make FlexibleSpaceBar title padding configurable (#27623)
This commit is contained in:
parent
bcd60fa89a
commit
022f7d892e
@ -47,6 +47,7 @@ class FlexibleSpaceBar extends StatefulWidget {
|
||||
this.title,
|
||||
this.background,
|
||||
this.centerTitle,
|
||||
this.titlePadding,
|
||||
this.collapseMode = CollapseMode.parallax
|
||||
}) : assert(collapseMode != null),
|
||||
super(key: key);
|
||||
@ -63,7 +64,8 @@ class FlexibleSpaceBar extends StatefulWidget {
|
||||
|
||||
/// Whether the title should be centered.
|
||||
///
|
||||
/// Defaults to being adapted to the current [TargetPlatform].
|
||||
/// By default this property is true if the current target platform
|
||||
/// is [TargetPlatform.iOS], false otherwise.
|
||||
final bool centerTitle;
|
||||
|
||||
/// Collapse effect while scrolling.
|
||||
@ -71,6 +73,18 @@ class FlexibleSpaceBar extends StatefulWidget {
|
||||
/// Defaults to [CollapseMode.parallax].
|
||||
final CollapseMode collapseMode;
|
||||
|
||||
/// Defines how far the [title] is inset from either the widget's
|
||||
/// bottom-left or its center.
|
||||
///
|
||||
/// Typically this property is used to adjust how far the title is
|
||||
/// is inset from the bottom-left and it is specified along with
|
||||
/// [centerTitle] false.
|
||||
///
|
||||
/// By default the value of this property is
|
||||
/// `EdgeInsetsDirectional.only(start: 72, bottom: 16)` if the title is
|
||||
/// not centered, `EdgeInsetsDirectional.only(start 0, bottom: 16)` otherwise.
|
||||
final EdgeInsetsGeometry titlePadding;
|
||||
|
||||
/// Wraps a widget that contains an [AppBar] to convey sizing information down
|
||||
/// to the [FlexibleSpaceBar].
|
||||
///
|
||||
@ -206,15 +220,17 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
|
||||
color: titleStyle.color.withOpacity(opacity)
|
||||
);
|
||||
final bool effectiveCenterTitle = _getEffectiveCenterTitle(theme);
|
||||
final EdgeInsetsGeometry padding = widget.titlePadding ??
|
||||
EdgeInsetsDirectional.only(
|
||||
start: effectiveCenterTitle ? 0.0 : 72.0,
|
||||
bottom: 16.0
|
||||
);
|
||||
final double scaleValue = Tween<double>(begin: 1.5, end: 1.0).transform(t);
|
||||
final Matrix4 scaleTransform = Matrix4.identity()
|
||||
..scale(scaleValue, scaleValue, 1.0);
|
||||
final Alignment titleAlignment = _getTitleAlignment(effectiveCenterTitle);
|
||||
children.add(Container(
|
||||
padding: EdgeInsetsDirectional.only(
|
||||
start: effectiveCenterTitle ? 0.0 : 72.0,
|
||||
bottom: 16.0
|
||||
),
|
||||
padding: padding,
|
||||
child: Transform(
|
||||
alignment: titleAlignment,
|
||||
transform: scaleTransform,
|
||||
|
@ -114,6 +114,88 @@ void main() {
|
||||
|
||||
expect(clipRect.size.height, minExtent);
|
||||
});
|
||||
|
||||
testWidgets('FlexibleSpaceBar test titlePadding defaults', (WidgetTester tester) async {
|
||||
Widget buildFrame(TargetPlatform platform, bool centerTitle) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(platform: platform),
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
centerTitle: centerTitle,
|
||||
title: const Text('X'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final Finder title = find.text('X');
|
||||
final Finder flexibleSpaceBar = find.byType(FlexibleSpaceBar);
|
||||
Offset getTitleBottomLeft() {
|
||||
return Offset(
|
||||
tester.getTopLeft(title).dx,
|
||||
tester.getBottomRight(flexibleSpaceBar).dy - tester.getBottomRight(title).dy,
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildFrame(TargetPlatform.android, null));
|
||||
expect(getTitleBottomLeft(), const Offset(72.0, 16.0));
|
||||
|
||||
await tester.pumpWidget(buildFrame(TargetPlatform.android, true));
|
||||
expect(getTitleBottomLeft(), const Offset(390.0, 16.0));
|
||||
|
||||
// Clear the widget tree to avoid animating between Android and iOS.
|
||||
await tester.pumpWidget(Container(key: UniqueKey()));
|
||||
|
||||
await tester.pumpWidget(buildFrame(TargetPlatform.iOS, null));
|
||||
expect(getTitleBottomLeft(), const Offset(390.0, 16.0));
|
||||
|
||||
await tester.pumpWidget(buildFrame(TargetPlatform.iOS, false));
|
||||
expect(getTitleBottomLeft(), const Offset(72.0, 16.0));
|
||||
|
||||
});
|
||||
|
||||
testWidgets('FlexibleSpaceBar test titlePadding override', (WidgetTester tester) async {
|
||||
Widget buildFrame(TargetPlatform platform, bool centerTitle) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(platform: platform),
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
titlePadding: EdgeInsets.zero,
|
||||
centerTitle: centerTitle,
|
||||
title: const Text('X'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final Finder title = find.text('X');
|
||||
final Finder flexibleSpaceBar = find.byType(FlexibleSpaceBar);
|
||||
Offset getTitleBottomLeft() {
|
||||
return Offset(
|
||||
tester.getTopLeft(title).dx,
|
||||
tester.getBottomRight(flexibleSpaceBar).dy - tester.getBottomRight(title).dy,
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildFrame(TargetPlatform.android, null));
|
||||
expect(getTitleBottomLeft(), Offset.zero);
|
||||
|
||||
await tester.pumpWidget(buildFrame(TargetPlatform.android, true));
|
||||
expect(getTitleBottomLeft(), const Offset(390.0, 0.0));
|
||||
|
||||
// Clear the widget tree to avoid animating between Android and iOS.
|
||||
await tester.pumpWidget(Container(key: UniqueKey()));
|
||||
|
||||
await tester.pumpWidget(buildFrame(TargetPlatform.iOS, null));
|
||||
expect(getTitleBottomLeft(), const Offset(390.0, 0.0));
|
||||
|
||||
await tester.pumpWidget(buildFrame(TargetPlatform.iOS, false));
|
||||
expect(getTitleBottomLeft(), Offset.zero);
|
||||
});
|
||||
}
|
||||
|
||||
class TestDelegate extends SliverPersistentHeaderDelegate {
|
||||
|
Loading…
x
Reference in New Issue
Block a user