Unverified Commit a67ba2a2 authored by Ayush Bherwani's avatar Ayush Bherwani Committed by GitHub

[AppBarTheme] adds titleSpacing parameter (#67105)

* adds titleSpacing in AppBarTheme
Co-authored-by: 's avatarShi-Hao Hong <shihaohong@google.com>
parent 73137401
......@@ -203,7 +203,7 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
this.primary = true,
this.centerTitle,
this.excludeHeaderSemantics = false,
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.titleSpacing,
this.toolbarOpacity = 1.0,
this.bottomOpacity = 1.0,
this.toolbarHeight,
......@@ -211,7 +211,6 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
}) : assert(automaticallyImplyLeading != null),
assert(elevation == null || elevation >= 0.0),
assert(primary != null),
assert(titleSpacing != null),
assert(toolbarOpacity != null),
assert(bottomOpacity != null),
preferredSize = Size.fromHeight(toolbarHeight ?? kToolbarHeight + (bottom?.preferredSize.height ?? 0.0)),
......@@ -424,7 +423,7 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
/// [title] to take all the space available, set this value to 0.0.
///
/// Defaults to [NavigationToolbar.kMiddleSpacing].
final double titleSpacing;
final double? titleSpacing;
/// How opaque the toolbar part of the app bar is.
///
......@@ -634,7 +633,7 @@ class _AppBarState extends State<AppBar> {
middle: title,
trailing: actions,
centerMiddle: widget._getEffectiveCenterTitle(theme!),
middleSpacing: widget.titleSpacing,
middleSpacing: widget.titleSpacing ?? appBarTheme.titleSpacing ?? NavigationToolbar.kMiddleSpacing,
);
// If the toolbar is allocated less than toolbarHeight make it
......@@ -848,7 +847,7 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
final bool primary;
final bool? centerTitle;
final bool excludeHeaderSemantics;
final double titleSpacing;
final double? titleSpacing;
final double? expandedHeight;
final double collapsedHeight;
final double topPadding;
......@@ -1064,7 +1063,7 @@ class SliverAppBar extends StatefulWidget {
this.primary = true,
this.centerTitle,
this.excludeHeaderSemantics = false,
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.titleSpacing,
this.collapsedHeight,
this.expandedHeight,
this.floating = false,
......@@ -1079,7 +1078,6 @@ class SliverAppBar extends StatefulWidget {
}) : assert(automaticallyImplyLeading != null),
assert(forceElevated != null),
assert(primary != null),
assert(titleSpacing != null),
assert(floating != null),
assert(pinned != null),
assert(snap != null),
......@@ -1259,7 +1257,7 @@ class SliverAppBar extends StatefulWidget {
/// [title] to take all the space available, set this value to 0.0.
///
/// Defaults to [NavigationToolbar.kMiddleSpacing].
final double titleSpacing;
final double? titleSpacing;
/// Defines the height of the app bar when it is collapsed.
///
......
......@@ -39,6 +39,7 @@ class AppBarTheme with Diagnosticable {
this.actionsIconTheme,
this.textTheme,
this.centerTitle,
this.titleSpacing,
});
/// Default value for [AppBar.brightness].
......@@ -81,6 +82,11 @@ class AppBarTheme with Diagnosticable {
/// If null, the value is adapted to current [TargetPlatform].
final bool? centerTitle;
/// Default value for [AppBar.titleSpacing].
///
/// If null, [AppBar] uses default value of [NavigationToolbar.kMiddleSpacing].
final double? titleSpacing;
/// Creates a copy of this object with the given fields replaced with the
/// new values.
AppBarTheme copyWith({
......@@ -92,6 +98,7 @@ class AppBarTheme with Diagnosticable {
IconThemeData? iconTheme,
TextTheme? textTheme,
bool? centerTitle,
double? titleSpacing,
}) {
return AppBarTheme(
brightness: brightness ?? this.brightness,
......@@ -102,6 +109,7 @@ class AppBarTheme with Diagnosticable {
actionsIconTheme: actionsIconTheme ?? this.actionsIconTheme,
textTheme: textTheme ?? this.textTheme,
centerTitle: centerTitle ?? this.centerTitle,
titleSpacing: titleSpacing ?? this.titleSpacing,
);
}
......@@ -126,6 +134,7 @@ class AppBarTheme with Diagnosticable {
actionsIconTheme: IconThemeData.lerp(a?.actionsIconTheme, b?.actionsIconTheme, t),
textTheme: TextTheme.lerp(a?.textTheme, b?.textTheme, t),
centerTitle: t < 0.5 ? a?.centerTitle : b?.centerTitle,
titleSpacing: lerpDouble(a?.titleSpacing, b?.titleSpacing, t),
);
}
......@@ -140,6 +149,7 @@ class AppBarTheme with Diagnosticable {
actionsIconTheme,
textTheme,
centerTitle,
titleSpacing,
);
}
......@@ -157,7 +167,8 @@ class AppBarTheme with Diagnosticable {
&& other.iconTheme == iconTheme
&& other.actionsIconTheme == actionsIconTheme
&& other.textTheme == textTheme
&& other.centerTitle == centerTitle;
&& other.centerTitle == centerTitle
&& other.titleSpacing == titleSpacing;
}
@override
......@@ -171,5 +182,6 @@ class AppBarTheme with Diagnosticable {
properties.add(DiagnosticsProperty<IconThemeData>('actionsIconTheme', actionsIconTheme, defaultValue: null));
properties.add(DiagnosticsProperty<TextTheme>('textTheme', textTheme, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('centerTitle', centerTitle, defaultValue: null));
properties.add(DiagnosticsProperty<double>('titleSpacing', titleSpacing, defaultValue: null));
}
}
......@@ -2211,4 +2211,27 @@ void main() {
NavigationToolbar getAppBarWidget(Finder finder) => tester.widget<NavigationToolbar>(finder);
expect(getAppBarWidget(appBarFinder).leading, null);
});
testWidgets('AppBar.titleSpacing defaults to NavigationToolbar.kMiddleSpacing', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
),
));
final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
expect(navToolBar.middleSpacing, NavigationToolbar.kMiddleSpacing);
});
testWidgets('SliverAppBar.titleSpacing defaults to NavigationToolbar.kMiddleSpacing', (WidgetTester tester) async {
await tester.pumpWidget(buildSliverAppBarApp(
floating: false,
pinned: false,
));
final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
expect(navToolBar.middleSpacing, NavigationToolbar.kMiddleSpacing);
});
}
......@@ -7,6 +7,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
......@@ -245,6 +246,116 @@ void main() {
// The AppBar.shadowColor should be used instead of AppBarTheme.shadowColor.
expect(appBar.shadowColor, Colors.yellow);
});
testWidgets('AppBar uses AppBarTheme.titleSpacing', (WidgetTester tester) async {
const double kTitleSpacing = 10;
await tester.pumpWidget(MaterialApp(
theme: ThemeData(appBarTheme: const AppBarTheme(titleSpacing: kTitleSpacing)),
home: Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
),
));
final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
expect(navToolBar.middleSpacing, kTitleSpacing);
});
testWidgets('AppBar.titleSpacing takes priority over AppBarTheme.titleSpacing', (WidgetTester tester) async {
const double kTitleSpacing = 10;
await tester.pumpWidget(MaterialApp(
theme: ThemeData(appBarTheme: const AppBarTheme(titleSpacing: kTitleSpacing)),
home: Scaffold(
appBar: AppBar(
title: const Text('Title'),
titleSpacing: 40,
),
),
));
final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
expect(navToolBar.middleSpacing, 40);
});
testWidgets('SliverAppBar uses AppBarTheme.titleSpacing', (WidgetTester tester) async {
const double kTitleSpacing = 10;
await tester.pumpWidget(MaterialApp(
theme: ThemeData(appBarTheme: const AppBarTheme(titleSpacing: kTitleSpacing)),
home: const CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: Text('Title'),
),
],
),
));
final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
expect(navToolBar.middleSpacing, kTitleSpacing);
});
testWidgets('SliverAppBar.titleSpacing takes priority over AppBarTheme.titleSpacing ', (WidgetTester tester) async {
const double kTitleSpacing = 10;
await tester.pumpWidget(MaterialApp(
theme: ThemeData(appBarTheme: const AppBarTheme(titleSpacing: kTitleSpacing)),
home: const CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: Text('Title'),
titleSpacing: 40,
),
],
),
));
final NavigationToolbar navToolbar = tester.widget(find.byType(NavigationToolbar));
expect(navToolbar.middleSpacing, 40);
});
testWidgets('Default AppBarTheme debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const AppBarTheme().debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[]);
});
testWidgets('AppBarTheme implements debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const AppBarTheme(
brightness: Brightness.dark,
color: Color(0xff000001),
elevation: 8.0,
shadowColor: Color(0xff000002),
centerTitle: true,
titleSpacing: 40.0,
).debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[
'brightness: Brightness.dark',
'color: Color(0xff000001)',
'elevation: 8.0',
'shadowColor: Color(0xff000002)',
'centerTitle: true',
'titleSpacing: 40.0',
]);
// On the web, Dart doubles and ints are backed by the same kind of object because
// JavaScript does not support integers. So, the Dart double "4.0" is identical
// to "4", which results in the web evaluating to the value "4" regardless of which
// one is used. This results in a difference for doubles in debugFillProperties between
// the web and the rest of Flutter's target platforms.
}, skip: kIsWeb);
}
AppBarTheme _appBarTheme() {
......
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