Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
14a9b4a7
Unverified
Commit
14a9b4a7
authored
Apr 27, 2022
by
Darren Austin
Committed by
GitHub
Apr 27, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate AppBar to Material 3 (#101884)
parent
0c3c38dc
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
554 additions
and
149 deletions
+554
-149
gen_defaults.dart
dev/tools/gen_defaults/bin/gen_defaults.dart
+2
-0
app_bar_template.dart
dev/tools/gen_defaults/lib/app_bar_template.dart
+58
-0
app_bar.dart
packages/flutter/lib/src/material/app_bar.dart
+187
-30
app_bar_theme.dart
packages/flutter/lib/src/material/app_bar_theme.dart
+22
-0
material.dart
packages/flutter/lib/src/material/material.dart
+20
-13
theme_data.dart
packages/flutter/lib/src/material/theme_data.dart
+1
-0
app_bar_test.dart
packages/flutter/test/material/app_bar_test.dart
+92
-38
app_bar_theme_test.dart
packages/flutter/test/material/app_bar_theme_test.dart
+172
-68
No files found.
dev/tools/gen_defaults/bin/gen_defaults.dart
View file @
14a9b4a7
...
...
@@ -17,6 +17,7 @@
import
'dart:convert'
;
import
'dart:io'
;
import
'package:gen_defaults/app_bar_template.dart'
;
import
'package:gen_defaults/button_template.dart'
;
import
'package:gen_defaults/card_template.dart'
;
import
'package:gen_defaults/dialog_template.dart'
;
...
...
@@ -78,6 +79,7 @@ Future<void> main(List<String> args) async {
tokens
[
'colorsLight'
]
=
_readTokenFile
(
'color_light.json'
);
tokens
[
'colorsDark'
]
=
_readTokenFile
(
'color_dark.json'
);
AppBarTemplate
(
'
$materialLib
/app_bar.dart'
,
tokens
).
updateFile
();
ButtonTemplate
(
'md.comp.elevated-button'
,
'
$materialLib
/elevated_button.dart'
,
tokens
).
updateFile
();
ButtonTemplate
(
'md.comp.outlined-button'
,
'
$materialLib
/outlined_button.dart'
,
tokens
).
updateFile
();
ButtonTemplate
(
'md.comp.text-button'
,
'
$materialLib
/text_button.dart'
,
tokens
).
updateFile
();
...
...
dev/tools/gen_defaults/lib/app_bar_template.dart
0 → 100644
View file @
14a9b4a7
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'template.dart'
;
class
AppBarTemplate
extends
TokenTemplate
{
const
AppBarTemplate
(
super
.
fileName
,
super
.
tokens
)
:
super
(
colorSchemePrefix:
'_colors.'
,
textThemePrefix:
'_textTheme.'
,
);
@override
String
generate
()
=>
'''
// Generated version
${tokens["version"]}
class _TokenDefaultsM3 extends AppBarTheme {
_TokenDefaultsM3(this.context)
: super(
elevation:
${elevation('md.comp.top-app-bar.small.container')}
,
scrolledUnderElevation:
${elevation('md.comp.top-app-bar.small.on-scroll.container')}
,
titleSpacing: NavigationToolbar.kMiddleSpacing,
toolbarHeight:
${tokens['md.comp.top-app-bar.small.container.height']}
,
);
final BuildContext context;
late final ThemeData _theme = Theme.of(context);
late final ColorScheme _colors = _theme.colorScheme;
late final TextTheme _textTheme = _theme.textTheme;
@override
Color? get backgroundColor =>
${componentColor('md.comp.top-app-bar.small.container')}
;
@override
Color? get foregroundColor =>
${color('md.comp.top-app-bar.small.headline.color')}
;
@override
Color? get surfaceTintColor =>
${componentColor('md.comp.top-app-bar.small.container.surface-tint-layer')}
;
@override
IconThemeData? get iconTheme => IconThemeData(
color:
${componentColor('md.comp.top-app-bar.small.leading-icon')}
,
size:
${tokens['md.comp.top-app-bar.small.leading-icon.size']}
,
);
@override
IconThemeData? get actionsIconTheme => IconThemeData(
color:
${componentColor('md.comp.top-app-bar.small.trailing-icon')}
,
size:
${tokens['md.comp.top-app-bar.small.trailing-icon.size']}
,
);
@override
TextStyle? get toolbarTextStyle => _textTheme.bodyText2;
@override
TextStyle? get titleTextStyle =>
${textStyle('md.comp.top-app-bar.small.headline')}
;
}'''
;
}
packages/flutter/lib/src/material/app_bar.dart
View file @
14a9b4a7
...
...
@@ -161,7 +161,9 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
this
.
flexibleSpace
,
this
.
bottom
,
this
.
elevation
,
this
.
scrolledUnderElevation
,
this
.
shadowColor
,
this
.
surfaceTintColor
,
this
.
shape
,
this
.
backgroundColor
,
this
.
foregroundColor
,
...
...
@@ -372,7 +374,12 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
/// {@template flutter.material.appbar.elevation}
/// The z-coordinate at which to place this app bar relative to its parent.
///
/// This property controls the size of the shadow below the app bar.
/// This property controls the size of the shadow below the app bar if
/// [shadowColor] is not null.
///
/// If [surfaceTintColor] is not null then it will apply a surface tint overlay
/// to the background color (see [Material.surfaceTintColor] for more
/// detail).
///
/// The value must be non-negative.
///
...
...
@@ -383,11 +390,37 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
///
/// See also:
///
/// * [scrolledUnderElevation], which will be used when the app bar has
/// something scrolled underneath it.
/// * [shadowColor], which is the color of the shadow below the app bar.
/// * [surfaceTintColor], which determines the elevation overlay that will
/// be applied to the background of the app bar.
/// * [shape], which defines the shape of the app bar's [Material] and its
/// shadow.
final
double
?
elevation
;
/// {@template flutter.material.appbar.scrolledUnderElevation}
/// The elevation that will be used if this app bar has something
/// scrolled underneath it.
///
/// If non-null then it [AppBarTheme.scrolledUnderElevation] of
/// [ThemeData.appBarTheme] will be used. If that is also null then [elevation]
/// will be used.
///
/// The value must be non-negative.
///
/// {@endtemplate}
///
/// See also:
/// * [elevation], which will be used if there is no content scrolled under
/// the app bar.
/// * [shadowColor], which is the color of the shadow below the app bar.
/// * [surfaceTintColor], which determines the elevation overlay that will
/// be applied to the background of the app bar.
/// * [shape], which defines the shape of the app bar's [Material] and its
/// shadow.
final
double
?
scrolledUnderElevation
;
/// {@template flutter.material.appbar.shadowColor}
/// The color of the shadow below the app bar.
///
...
...
@@ -402,6 +435,17 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
/// * [shape], which defines the shape of the app bar and its shadow.
final
Color
?
shadowColor
;
/// {@template flutter.material.appbar.surfaceTintColor}
/// The color of the surface tint overlay applied to the app bar's
/// background color to indicate elevation.
///
/// If null no overlay will be applied.
/// {@endtemplate}
///
/// See also:
/// * [Material.surfaceTintColor], which described this feature in more detail.
final
Color
?
surfaceTintColor
;
/// {@template flutter.material.appbar.shape}
/// The shape of the app bar's [Material] as well as its shadow.
///
...
...
@@ -709,12 +753,8 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
/// * [SystemChrome.setSystemUIOverlayStyle]
final
SystemUiOverlayStyle
?
systemOverlayStyle
;
bool
_getEffectiveCenterTitle
(
ThemeData
theme
)
{
if
(
centerTitle
!=
null
)
return
centerTitle
!;
if
(
theme
.
appBarTheme
.
centerTitle
!=
null
)
return
theme
.
appBarTheme
.
centerTitle
!;
bool
platformCenter
()
{
assert
(
theme
.
platform
!=
null
);
switch
(
theme
.
platform
)
{
case
TargetPlatform
.
android
:
...
...
@@ -728,14 +768,16 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
}
}
return
centerTitle
??
theme
.
appBarTheme
.
centerTitle
??
platformCenter
();
}
@override
State
<
AppBar
>
createState
()
=>
_AppBarState
();
}
class
_AppBarState
extends
State
<
AppBar
>
{
static
const
double
_defaultElevation
=
4.0
;
static
const
Color
_defaultShadowColor
=
Color
(
0xFF000000
);
ScrollNotificationObserverState
?
_scrollNotificationObserver
;
bool
_scrolledUnder
=
false
;
...
...
@@ -795,8 +837,8 @@ class _AppBarState extends State<AppBar> {
assert
(!
widget
.
primary
||
debugCheckHasMediaQuery
(
context
));
assert
(
debugCheckHasMaterialLocalizations
(
context
));
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
ColorScheme
colorScheme
=
theme
.
colorScheme
;
final
AppBarTheme
appBarTheme
=
AppBarTheme
.
of
(
context
);
final
AppBarTheme
defaults
=
theme
.
useMaterial3
?
_TokenDefaultsM3
(
context
)
:
_DefaultsM2
(
context
);
final
ScaffoldState
?
scaffold
=
Scaffold
.
maybeOf
(
context
);
final
ModalRoute
<
dynamic
>?
parentRoute
=
ModalRoute
.
of
(
context
);
...
...
@@ -821,12 +863,23 @@ class _AppBarState extends State<AppBar> {
states
,
widget
.
backgroundColor
,
appBarTheme
.
backgroundColor
,
colorScheme
.
brightness
==
Brightness
.
dark
?
colorScheme
.
surface
:
colorScheme
.
primary
,
defaults
.
backgroundColor
!
,
);
final
Color
foregroundColor
=
widget
.
foregroundColor
??
appBarTheme
.
foregroundColor
??
(
colorScheme
.
brightness
==
Brightness
.
dark
?
colorScheme
.
onSurface
:
colorScheme
.
onPrimary
);
??
defaults
.
foregroundColor
!;
final
double
elevation
=
widget
.
elevation
??
appBarTheme
.
elevation
??
defaults
.
elevation
!;
final
double
effectiveElevation
=
states
.
contains
(
MaterialState
.
scrolledUnder
)
?
widget
.
scrolledUnderElevation
??
appBarTheme
.
scrolledUnderElevation
??
defaults
.
scrolledUnderElevation
??
elevation
:
elevation
;
IconThemeData
overallIconTheme
=
backwardsCompatibility
?
widget
.
iconTheme
...
...
@@ -834,10 +887,13 @@ class _AppBarState extends State<AppBar> {
??
theme
.
primaryIconTheme
:
widget
.
iconTheme
??
appBarTheme
.
iconTheme
??
theme
.
iconTheme
.
copyWith
(
color:
foregroundColor
);
??
defaults
.
iconTheme
!
.
copyWith
(
color:
foregroundColor
);
IconThemeData
actionsIconTheme
=
widget
.
actionsIconTheme
??
appBarTheme
.
actionsIconTheme
??
widget
.
iconTheme
??
appBarTheme
.
iconTheme
??
defaults
.
actionsIconTheme
?.
copyWith
(
color:
foregroundColor
)
??
overallIconTheme
;
TextStyle
?
toolbarTextStyle
=
backwardsCompatibility
...
...
@@ -846,7 +902,7 @@ class _AppBarState extends State<AppBar> {
??
theme
.
primaryTextTheme
.
bodyText2
:
widget
.
toolbarTextStyle
??
appBarTheme
.
toolbarTextStyle
??
theme
.
textTheme
.
bodyText2
?.
copyWith
(
color:
foregroundColor
);
??
defaults
.
toolbarTextStyle
?.
copyWith
(
color:
foregroundColor
);
TextStyle
?
titleTextStyle
=
backwardsCompatibility
?
widget
.
textTheme
?.
headline6
...
...
@@ -854,7 +910,7 @@ class _AppBarState extends State<AppBar> {
??
theme
.
primaryTextTheme
.
headline6
:
widget
.
titleTextStyle
??
appBarTheme
.
titleTextStyle
??
theme
.
textTheme
.
headline6
?.
copyWith
(
color:
foregroundColor
);
??
defaults
.
titleTextStyle
?.
copyWith
(
color:
foregroundColor
);
if
(
widget
.
toolbarOpacity
!=
1.0
)
{
final
double
opacity
=
const
Interval
(
0.25
,
1.0
,
curve:
Curves
.
fastOutSlowIn
).
transform
(
widget
.
toolbarOpacity
);
...
...
@@ -1050,6 +1106,7 @@ class _AppBarState extends State<AppBar> {
)
:
widget
.
systemOverlayStyle
??
appBarTheme
.
systemOverlayStyle
??
defaults
.
systemOverlayStyle
??
_systemOverlayStyleForBrightness
(
ThemeData
.
estimateBrightnessForColor
(
backgroundColor
));
return
Semantics
(
...
...
@@ -1058,13 +1115,14 @@ class _AppBarState extends State<AppBar> {
value:
overlayStyle
,
child:
Material
(
color:
backgroundColor
,
elevation:
widget
.
elevation
??
appBarTheme
.
elevation
??
_defaultElevation
,
elevation:
effectiveElevation
,
shadowColor:
widget
.
shadowColor
??
appBarTheme
.
shadowColor
??
_defaultShadowColor
,
shape:
widget
.
shape
??
appBarTheme
.
shape
,
??
defaults
.
shadowColor
,
surfaceTintColor:
widget
.
surfaceTintColor
??
appBarTheme
.
surfaceTintColor
??
defaults
.
surfaceTintColor
,
shape:
widget
.
shape
??
appBarTheme
.
shape
??
defaults
.
shape
,
child:
Semantics
(
explicitChildNodes:
true
,
child:
appBar
,
...
...
@@ -1084,7 +1142,9 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
required
this
.
flexibleSpace
,
required
this
.
bottom
,
required
this
.
elevation
,
required
this
.
scrolledUnderElevation
,
required
this
.
shadowColor
,
required
this
.
surfaceTintColor
,
required
this
.
forceElevated
,
required
this
.
backgroundColor
,
required
this
.
foregroundColor
,
...
...
@@ -1126,7 +1186,9 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
final
Widget
?
flexibleSpace
;
final
PreferredSizeWidget
?
bottom
;
final
double
?
elevation
;
final
double
?
scrolledUnderElevation
;
final
Color
?
shadowColor
;
final
Color
?
surfaceTintColor
;
final
bool
forceElevated
;
final
Color
?
backgroundColor
;
final
Color
?
foregroundColor
;
...
...
@@ -1201,7 +1263,9 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
:
flexibleSpace
,
bottom:
bottom
,
elevation:
forceElevated
||
isScrolledUnder
?
elevation
:
0.0
,
scrolledUnderElevation:
scrolledUnderElevation
,
shadowColor:
shadowColor
,
surfaceTintColor:
surfaceTintColor
,
backgroundColor:
backgroundColor
,
foregroundColor:
foregroundColor
,
brightness:
brightness
,
...
...
@@ -1368,7 +1432,9 @@ class SliverAppBar extends StatefulWidget {
this
.
flexibleSpace
,
this
.
bottom
,
this
.
elevation
,
this
.
scrolledUnderElevation
,
this
.
shadowColor
,
this
.
surfaceTintColor
,
this
.
forceElevated
=
false
,
this
.
backgroundColor
,
this
.
foregroundColor
,
...
...
@@ -1454,11 +1520,21 @@ class SliverAppBar extends StatefulWidget {
/// This property is used to configure an [AppBar].
final
double
?
elevation
;
/// {@macro flutter.material.appbar.scrolledUnderElevation}
///
/// This property is used to configure an [AppBar].
final
double
?
scrolledUnderElevation
;
/// {@macro flutter.material.appbar.shadowColor}
///
/// This property is used to configure an [AppBar].
final
Color
?
shadowColor
;
/// {@macro flutter.material.appbar.surfaceTintColor}
///
/// This property is used to configure an [AppBar].
final
Color
?
surfaceTintColor
;
/// Whether to show the shadow appropriate for the [elevation] even if the
/// content is not scrolled under the [AppBar].
///
...
...
@@ -1760,7 +1836,9 @@ class _SliverAppBarState extends State<SliverAppBar> with TickerProviderStateMix
flexibleSpace:
widget
.
flexibleSpace
,
bottom:
widget
.
bottom
,
elevation:
widget
.
elevation
,
scrolledUnderElevation:
widget
.
scrolledUnderElevation
,
shadowColor:
widget
.
shadowColor
,
surfaceTintColor:
widget
.
surfaceTintColor
,
forceElevated:
widget
.
forceElevated
,
backgroundColor:
widget
.
backgroundColor
,
foregroundColor:
widget
.
foregroundColor
,
...
...
@@ -1832,3 +1910,82 @@ class _RenderAppBarTitleBox extends RenderAligningShiftedBox {
alignChild
();
}
}
class
_DefaultsM2
extends
AppBarTheme
{
_DefaultsM2
(
this
.
context
)
:
super
(
elevation:
4.0
,
shadowColor:
const
Color
(
0xFF000000
),
titleSpacing:
NavigationToolbar
.
kMiddleSpacing
,
toolbarHeight:
kToolbarHeight
,
);
final
BuildContext
context
;
late
final
ThemeData
_theme
=
Theme
.
of
(
context
);
late
final
ColorScheme
_colors
=
_theme
.
colorScheme
;
@override
Color
?
get
backgroundColor
=>
_colors
.
brightness
==
Brightness
.
dark
?
_colors
.
surface
:
_colors
.
primary
;
@override
Color
?
get
foregroundColor
=>
_colors
.
brightness
==
Brightness
.
dark
?
_colors
.
onSurface
:
_colors
.
onPrimary
;
@override
IconThemeData
?
get
iconTheme
=>
_theme
.
iconTheme
;
@override
TextStyle
?
get
toolbarTextStyle
=>
_theme
.
textTheme
.
bodyText2
;
@override
TextStyle
?
get
titleTextStyle
=>
_theme
.
textTheme
.
headline6
;
}
// BEGIN GENERATED TOKEN PROPERTIES
// Generated code to the end of this file. Do not edit by hand.
// These defaults are generated from the Material Design Token
// database by the script dev/tools/gen_defaults/bin/gen_defaults.dart.
// Generated version v0_92
class
_TokenDefaultsM3
extends
AppBarTheme
{
_TokenDefaultsM3
(
this
.
context
)
:
super
(
elevation:
0.0
,
scrolledUnderElevation:
3.0
,
titleSpacing:
NavigationToolbar
.
kMiddleSpacing
,
toolbarHeight:
64.0
,
);
final
BuildContext
context
;
late
final
ThemeData
_theme
=
Theme
.
of
(
context
);
late
final
ColorScheme
_colors
=
_theme
.
colorScheme
;
late
final
TextTheme
_textTheme
=
_theme
.
textTheme
;
@override
Color
?
get
backgroundColor
=>
_colors
.
surface
;
@override
Color
?
get
foregroundColor
=>
_colors
.
onSurface
;
@override
Color
?
get
surfaceTintColor
=>
_colors
.
surfaceTint
;
@override
IconThemeData
?
get
iconTheme
=>
IconThemeData
(
color:
_colors
.
onSurface
,
size:
24.0
,
);
@override
IconThemeData
?
get
actionsIconTheme
=>
IconThemeData
(
color:
_colors
.
onSurfaceVariant
,
size:
24.0
,
);
@override
TextStyle
?
get
toolbarTextStyle
=>
_textTheme
.
bodyText2
;
@override
TextStyle
?
get
titleTextStyle
=>
_textTheme
.
titleLarge
;
}
// END GENERATED TOKEN PROPERTIES
packages/flutter/lib/src/material/app_bar_theme.dart
View file @
14a9b4a7
...
...
@@ -37,7 +37,9 @@ class AppBarTheme with Diagnosticable {
Color
?
backgroundColor
,
this
.
foregroundColor
,
this
.
elevation
,
this
.
scrolledUnderElevation
,
this
.
shadowColor
,
this
.
surfaceTintColor
,
this
.
shape
,
this
.
iconTheme
,
this
.
actionsIconTheme
,
...
...
@@ -121,10 +123,18 @@ class AppBarTheme with Diagnosticable {
/// descendant [AppBar] widgets.
final
double
?
elevation
;
/// Overrides the default value of [AppBar.scrolledUnderElevation] in all
/// descendant [AppBar] widgets.
final
double
?
scrolledUnderElevation
;
/// Overrides the default value for [AppBar.shadowColor] in all
/// descendant widgets.
final
Color
?
shadowColor
;
/// Overrides the default value for [AppBar.surfaceTintColor] in all
/// descendant widgets.
final
Color
?
surfaceTintColor
;
/// Overrides the default value for [AppBar.shape] in all
/// descendant widgets.
final
ShapeBorder
?
shape
;
...
...
@@ -237,7 +247,9 @@ class AppBarTheme with Diagnosticable {
Color
?
backgroundColor
,
Color
?
foregroundColor
,
double
?
elevation
,
double
?
scrolledUnderElevation
,
Color
?
shadowColor
,
Color
?
surfaceTintColor
,
ShapeBorder
?
shape
,
IconThemeData
?
iconTheme
,
@Deprecated
(
...
...
@@ -266,7 +278,9 @@ class AppBarTheme with Diagnosticable {
backgroundColor:
backgroundColor
??
color
??
this
.
backgroundColor
,
foregroundColor:
foregroundColor
??
this
.
foregroundColor
,
elevation:
elevation
??
this
.
elevation
,
scrolledUnderElevation:
scrolledUnderElevation
??
this
.
scrolledUnderElevation
,
shadowColor:
shadowColor
??
this
.
shadowColor
,
surfaceTintColor:
surfaceTintColor
??
this
.
surfaceTintColor
,
shape:
shape
??
this
.
shape
,
iconTheme:
iconTheme
??
this
.
iconTheme
,
actionsIconTheme:
actionsIconTheme
??
this
.
actionsIconTheme
,
...
...
@@ -298,7 +312,9 @@ class AppBarTheme with Diagnosticable {
backgroundColor:
Color
.
lerp
(
a
?.
backgroundColor
,
b
?.
backgroundColor
,
t
),
foregroundColor:
Color
.
lerp
(
a
?.
foregroundColor
,
b
?.
foregroundColor
,
t
),
elevation:
lerpDouble
(
a
?.
elevation
,
b
?.
elevation
,
t
),
scrolledUnderElevation:
lerpDouble
(
a
?.
scrolledUnderElevation
,
b
?.
scrolledUnderElevation
,
t
),
shadowColor:
Color
.
lerp
(
a
?.
shadowColor
,
b
?.
shadowColor
,
t
),
surfaceTintColor:
Color
.
lerp
(
a
?.
surfaceTintColor
,
b
?.
surfaceTintColor
,
t
),
shape:
ShapeBorder
.
lerp
(
a
?.
shape
,
b
?.
shape
,
t
),
iconTheme:
IconThemeData
.
lerp
(
a
?.
iconTheme
,
b
?.
iconTheme
,
t
),
actionsIconTheme:
IconThemeData
.
lerp
(
a
?.
actionsIconTheme
,
b
?.
actionsIconTheme
,
t
),
...
...
@@ -319,7 +335,9 @@ class AppBarTheme with Diagnosticable {
backgroundColor
,
foregroundColor
,
elevation
,
scrolledUnderElevation
,
shadowColor
,
surfaceTintColor
,
shape
,
iconTheme
,
actionsIconTheme
,
...
...
@@ -344,7 +362,9 @@ class AppBarTheme with Diagnosticable {
&&
other
.
backgroundColor
==
backgroundColor
&&
other
.
foregroundColor
==
foregroundColor
&&
other
.
elevation
==
elevation
&&
other
.
scrolledUnderElevation
==
scrolledUnderElevation
&&
other
.
shadowColor
==
shadowColor
&&
other
.
surfaceTintColor
==
surfaceTintColor
&&
other
.
shape
==
shape
&&
other
.
iconTheme
==
iconTheme
&&
other
.
actionsIconTheme
==
actionsIconTheme
...
...
@@ -365,7 +385,9 @@ class AppBarTheme with Diagnosticable {
properties
.
add
(
ColorProperty
(
'backgroundColor'
,
backgroundColor
,
defaultValue:
null
));
properties
.
add
(
ColorProperty
(
'foregroundColor'
,
foregroundColor
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
double
>(
'elevation'
,
elevation
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
double
>(
'scrolledUnderElevation'
,
scrolledUnderElevation
,
defaultValue:
null
));
properties
.
add
(
ColorProperty
(
'shadowColor'
,
shadowColor
,
defaultValue:
null
));
properties
.
add
(
ColorProperty
(
'surfaceTintColor'
,
surfaceTintColor
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
ShapeBorder
>(
'shape'
,
shape
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
IconThemeData
>(
'iconTheme'
,
iconTheme
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
IconThemeData
>(
'actionsIconTheme'
,
actionsIconTheme
,
defaultValue:
null
));
...
...
packages/flutter/lib/src/material/material.dart
View file @
14a9b4a7
...
...
@@ -400,6 +400,9 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
Widget
build
(
BuildContext
context
)
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
Color
?
backgroundColor
=
_getBackgroundColor
(
context
);
final
Color
?
modelShadowColor
=
widget
.
shadowColor
??
(
theme
.
useMaterial3
?
null
:
theme
.
shadowColor
);
// If no shadow color is specified, use 0 for elevation in the model so a drop shadow won't be painted.
final
double
modelElevation
=
modelShadowColor
!=
null
?
widget
.
elevation
:
0
;
assert
(
backgroundColor
!=
null
||
widget
.
type
==
MaterialType
.
transparency
,
'If Material type is not MaterialType.transparency, a color must '
...
...
@@ -449,9 +452,9 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
duration:
widget
.
animationDuration
,
shape:
BoxShape
.
rectangle
,
clipBehavior:
widget
.
clipBehavior
,
elevation:
widget
.
e
levation
,
elevation:
modelE
levation
,
color:
color
,
shadowColor:
widget
.
shadowColor
??
(
theme
.
useMaterial3
?
const
Color
(
0x00000000
)
:
theme
.
shadowColor
),
shadowColor:
modelShadowColor
??
const
Color
(
0x00000000
),
animateColor:
false
,
child:
contents
,
);
...
...
@@ -476,7 +479,7 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
clipBehavior:
widget
.
clipBehavior
,
elevation:
widget
.
elevation
,
color:
backgroundColor
!,
shadowColor:
widget
.
shadowColor
??
(
theme
.
useMaterial3
?
const
Color
(
0x00000000
)
:
theme
.
shadowColor
)
,
shadowColor:
modelShadowColor
,
surfaceTintColor:
widget
.
surfaceTintColor
,
child:
contents
,
);
...
...
@@ -742,8 +745,7 @@ class _MaterialInterior extends ImplicitlyAnimatedWidget {
assert
(
shape
!=
null
),
assert
(
clipBehavior
!=
null
),
assert
(
elevation
!=
null
&&
elevation
>=
0.0
),
assert
(
color
!=
null
),
assert
(
shadowColor
!=
null
);
assert
(
color
!=
null
);
/// The widget below this widget in the tree.
///
...
...
@@ -777,7 +779,7 @@ class _MaterialInterior extends ImplicitlyAnimatedWidget {
final
Color
color
;
/// The target shadow color.
final
Color
shadowColor
;
final
Color
?
shadowColor
;
/// The target surface tint color.
final
Color
?
surfaceTintColor
;
...
...
@@ -808,11 +810,13 @@ class _MaterialInteriorState extends AnimatedWidgetBaseState<_MaterialInterior>
widget
.
elevation
,
(
dynamic
value
)
=>
Tween
<
double
>(
begin:
value
as
double
),
)
as
Tween
<
double
>?;
_shadowColor
=
visitor
(
_shadowColor
=
widget
.
shadowColor
!=
null
?
visitor
(
_shadowColor
,
widget
.
shadowColor
,
(
dynamic
value
)
=>
ColorTween
(
begin:
value
as
Color
),
)
as
ColorTween
?;
)
as
ColorTween
?
:
null
;
_surfaceTintColor
=
widget
.
surfaceTintColor
!=
null
?
visitor
(
_surfaceTintColor
,
...
...
@@ -834,15 +838,18 @@ class _MaterialInteriorState extends AnimatedWidgetBaseState<_MaterialInterior>
final
Color
color
=
Theme
.
of
(
context
).
useMaterial3
?
ElevationOverlay
.
applySurfaceTint
(
widget
.
color
,
_surfaceTintColor
?.
evaluate
(
animation
),
elevation
)
:
ElevationOverlay
.
applyOverlay
(
context
,
widget
.
color
,
elevation
);
// If no shadow color is specified, use 0 for elevation in the model so a drop shadow won't be painted.
final
double
modelElevation
=
widget
.
shadowColor
!=
null
?
elevation
:
0
;
final
Color
shadowColor
=
_shadowColor
?.
evaluate
(
animation
)
??
const
Color
(
0x00000000
);
return
PhysicalShape
(
clipper:
ShapeBorderClipper
(
shape:
shape
,
textDirection:
Directionality
.
maybeOf
(
context
),
),
clipBehavior:
widget
.
clipBehavior
,
elevation:
e
levation
,
elevation:
modelE
levation
,
color:
color
,
shadowColor:
_shadowColor
!.
evaluate
(
animation
)!
,
shadowColor:
shadowColor
,
child:
_ShapeBorderPaint
(
shape:
shape
,
borderOnForeground:
widget
.
borderOnForeground
,
...
...
packages/flutter/lib/src/material/theme_data.dart
View file @
14a9b4a7
...
...
@@ -1203,6 +1203,7 @@ class ThemeData with Diagnosticable {
/// Components that have been migrated to Material 3 are:
///
/// * [AlertDialog]
/// * [AppBar]
/// * [Card]
/// * [Dialog]
/// * [ElevatedButton]
...
...
packages/flutter/test/material/app_bar_test.dart
View file @
14a9b4a7
...
...
@@ -954,6 +954,8 @@ void main() {
});
testWidgets
(
'AppBar uses the specified elevation or defaults to 4.0'
,
(
WidgetTester
tester
)
async
{
final
bool
useMaterial3
=
ThemeData
().
useMaterial3
;
Widget
buildAppBar
([
double
?
elevation
])
{
return
MaterialApp
(
home:
Scaffold
(
...
...
@@ -967,15 +969,48 @@ void main() {
matching:
find
.
byType
(
Material
),
));
// Default elevation should be
_AppBarState._defaultElevation = 4.0
// Default elevation should be
used for the material.
await
tester
.
pumpWidget
(
buildAppBar
());
expect
(
getMaterial
().
elevation
,
4.0
);
expect
(
getMaterial
().
elevation
,
useMaterial3
?
0
:
4
);
// AppBar should use the specified elevation.
await
tester
.
pumpWidget
(
buildAppBar
(
8.0
));
expect
(
getMaterial
().
elevation
,
8.0
);
});
testWidgets
(
'scrolledUnderElevation'
,
(
WidgetTester
tester
)
async
{
Widget
buildAppBar
({
double
?
elevation
,
double
?
scrolledUnderElevation
})
{
return
MaterialApp
(
home:
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'Title'
),
elevation:
elevation
,
scrolledUnderElevation:
scrolledUnderElevation
,
),
body:
ListView
.
builder
(
itemCount:
100
,
itemBuilder:
(
BuildContext
context
,
int
index
)
=>
ListTile
(
title:
Text
(
'Item
$index
'
)),
),
),
);
}
Material
getMaterial
()
=>
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
AppBar
),
matching:
find
.
byType
(
Material
),
));
await
tester
.
pumpWidget
(
buildAppBar
(
elevation:
2
,
scrolledUnderElevation:
10
));
// Starts with the base elevation.
expect
(
getMaterial
().
elevation
,
2
);
await
tester
.
fling
(
find
.
text
(
'Item 2'
),
const
Offset
(
0.0
,
-
600.0
),
2000.0
);
await
tester
.
pumpAndSettle
();
// After scrolling it should be the scrolledUnderElevation.
expect
(
getMaterial
().
elevation
,
10
);
});
group
(
'SliverAppBar elevation'
,
()
{
Widget
buildSliverAppBar
(
bool
forceElevated
,
{
double
?
elevation
,
double
?
themeElevation
})
{
return
MaterialApp
(
...
...
@@ -996,15 +1031,16 @@ void main() {
// Regression test for https://github.com/flutter/flutter/issues/59158.
AppBar
getAppBar
()
=>
tester
.
widget
<
AppBar
>(
find
.
byType
(
AppBar
));
Material
getMaterial
()
=>
tester
.
widget
<
Material
>(
find
.
byType
(
Material
));
final
bool
useMaterial3
=
ThemeData
().
useMaterial3
;
// When forceElevated is off, SliverAppBar should not be elevated.
await
tester
.
pumpWidget
(
buildSliverAppBar
(
false
));
expect
(
getMaterial
().
elevation
,
0.0
);
// Default elevation should be
_AppBarState._defaultElevation = 4.0, and
// Default elevation should be
used by the material, but
// the AppBar's elevation should not be specified by SliverAppBar.
await
tester
.
pumpWidget
(
buildSliverAppBar
(
true
));
expect
(
getMaterial
().
elevation
,
4.0
);
expect
(
getMaterial
().
elevation
,
useMaterial3
?
0.0
:
4.0
);
expect
(
getAppBar
().
elevation
,
null
);
// SliverAppBar should use the specified elevation.
...
...
@@ -1312,6 +1348,8 @@ void main() {
final
Key
key
=
UniqueKey
();
await
tester
.
pumpWidget
(
MaterialApp
(
// Test was designed against InkSplash so need to make sure that is used.
theme:
ThemeData
(
splashFactory:
InkSplash
.
splashFactory
),
home:
Center
(
child:
AppBar
(
title:
const
Text
(
'Abc'
),
...
...
@@ -2005,44 +2043,55 @@ void main() {
));
});
testWidgets
(
'
AppBar draws a light system bar for a light theme with a dark background
'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
lightTheme
=
ThemeData
(
primarySwatch:
Colors
.
deepOrange
);
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
lightT
heme
,
testWidgets
(
'
Default system bar brightness based on AppBar background color brightness.
'
,
(
WidgetTester
tester
)
async
{
Widget
buildAppBar
(
ThemeData
theme
)
{
return
MaterialApp
(
theme:
t
heme
,
home:
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'test'
),
appBar:
AppBar
(
title:
const
Text
(
'Title'
)),
),
);
}
// Using a light theme.
{
await
tester
.
pumpWidget
(
buildAppBar
(
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
light
())));
final
Material
appBarMaterial
=
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
AppBar
),
matching:
find
.
byType
(
Material
),
),
));
);
final
Brightness
appBarBrightness
=
ThemeData
.
estimateBrightnessForColor
(
appBarMaterial
.
color
!);
final
Brightness
onAppBarBrightness
=
appBarBrightness
==
Brightness
.
light
?
Brightness
.
dark
:
Brightness
.
light
;
expect
(
lightTheme
.
primaryColorBrightness
,
Brightness
.
dark
);
expect
(
lightTheme
.
colorScheme
.
brightness
,
Brightness
.
light
);
expect
(
SystemChrome
.
latestStyle
,
const
SystemUiOverlayStyle
(
statusBarBrightness:
Brightness
.
dark
,
statusBarIconBrightness:
Brightness
.
light
,
expect
(
SystemChrome
.
latestStyle
,
SystemUiOverlayStyle
(
statusBarBrightness:
appBarBrightness
,
statusBarIconBrightness:
onAppBarBrightness
,
));
});
}
testWidgets
(
'AppBar draws a dark system bar for a dark theme with a light background'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
darkTheme
=
ThemeData
(
brightness:
Brightness
.
dark
,
cardColor:
Colors
.
white
);
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
darkTheme
,
home:
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'test'
),
),
),
// Using a dark theme.
{
await
tester
.
pumpWidget
(
buildAppBar
(
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
dark
())));
final
Material
appBarMaterial
=
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
AppBar
),
matching:
find
.
byType
(
Material
),
),
);
final
Brightness
appBarBrightness
=
ThemeData
.
estimateBrightnessForColor
(
appBarMaterial
.
color
!);
final
Brightness
onAppBarBrightness
=
appBarBrightness
==
Brightness
.
light
?
Brightness
.
dark
:
Brightness
.
light
;
expect
(
darkTheme
.
primaryColorBrightness
,
Brightness
.
dark
);
expect
(
darkTheme
.
colorScheme
.
brightness
,
Brightness
.
dark
);
expect
(
SystemChrome
.
latestStyle
,
const
SystemUiOverlayStyle
(
statusBarBrightness:
Brightness
.
light
,
statusBarIconBrightness:
Brightness
.
dark
,
expect
(
SystemChrome
.
latestStyle
,
SystemUiOverlayStyle
(
statusBarBrightness:
appBarBrightness
,
statusBarIconBrightness:
onAppBarBrightness
,
));
}
});
testWidgets
(
'Changing SliverAppBar snap from true to false'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -2207,6 +2256,8 @@ void main() {
Widget
buildFrame
()
{
return
MaterialApp
(
// Test designed against 2014 font sizes.
theme:
ThemeData
(
textTheme:
Typography
.
englishLike2014
),
home:
Builder
(
builder:
(
BuildContext
context
)
{
return
MediaQuery
(
...
...
@@ -2245,6 +2296,8 @@ void main() {
Widget
buildFrame
()
{
return
MaterialApp
(
// Test designed against 2014 font sizes.
theme:
ThemeData
(
textTheme:
Typography
.
englishLike2014
),
home:
Builder
(
builder:
(
BuildContext
context
)
{
return
Directionality
(
...
...
@@ -2536,6 +2589,7 @@ void main() {
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
.
light
().
copyWith
(
useMaterial3:
false
,
appBarTheme:
const
AppBarTheme
(
backwardsCompatibility:
false
,
),
...
...
packages/flutter/test/material/app_bar_theme_test.dart
View file @
14a9b4a7
...
...
@@ -15,8 +15,10 @@ void main() {
});
testWidgets
(
'Passing no AppBarTheme returns defaults'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
theme
=
ThemeData
();
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
theme
,
home:
Scaffold
(
appBar:
AppBar
(
actions:
<
Widget
>[
...
...
@@ -33,10 +35,25 @@ void main() {
final
RichText
actionIconText
=
_getAppBarIconRichText
(
tester
);
final
DefaultTextStyle
text
=
_getAppBarText
(
tester
);
if
(
theme
.
useMaterial3
)
{
expect
(
SystemChrome
.
latestStyle
!.
statusBarBrightness
,
Brightness
.
light
);
expect
(
widget
.
color
,
theme
.
colorScheme
.
surface
);
expect
(
widget
.
elevation
,
0
);
expect
(
widget
.
shadowColor
,
null
);
expect
(
widget
.
surfaceTintColor
,
theme
.
colorScheme
.
surfaceTint
);
expect
(
widget
.
shape
,
null
);
expect
(
iconTheme
.
data
,
IconThemeData
(
color:
theme
.
colorScheme
.
onSurface
,
size:
24
));
expect
(
actionsIconTheme
.
data
,
IconThemeData
(
color:
theme
.
colorScheme
.
onSurfaceVariant
,
size:
24
));
expect
(
actionIconText
.
text
.
style
!.
color
,
Colors
.
black
);
expect
(
text
.
style
,
Typography
.
material2021
().
englishLike
.
bodyText2
!.
merge
(
Typography
.
material2021
().
black
.
bodyText2
).
copyWith
(
color:
theme
.
colorScheme
.
onSurface
));
expect
(
tester
.
getSize
(
find
.
byType
(
AppBar
)).
height
,
kToolbarHeight
);
expect
(
tester
.
getSize
(
find
.
byType
(
AppBar
)).
width
,
800
);
}
else
{
expect
(
SystemChrome
.
latestStyle
!.
statusBarBrightness
,
SystemUiOverlayStyle
.
light
.
statusBarBrightness
);
expect
(
widget
.
color
,
Colors
.
blue
);
expect
(
widget
.
elevation
,
4.0
);
expect
(
widget
.
shadowColor
,
Colors
.
black
);
expect
(
widget
.
surfaceTintColor
,
null
);
expect
(
widget
.
shape
,
null
);
expect
(
iconTheme
.
data
,
const
IconThemeData
(
color:
Colors
.
white
));
expect
(
actionsIconTheme
.
data
,
const
IconThemeData
(
color:
Colors
.
white
));
...
...
@@ -44,6 +61,7 @@ void main() {
expect
(
text
.
style
,
Typography
.
material2014
().
englishLike
.
bodyText2
!.
merge
(
Typography
.
material2014
().
white
.
bodyText2
));
expect
(
tester
.
getSize
(
find
.
byType
(
AppBar
)).
height
,
kToolbarHeight
);
expect
(
tester
.
getSize
(
find
.
byType
(
AppBar
)).
width
,
800
);
}
});
testWidgets
(
'AppBar uses values from AppBarTheme'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -73,6 +91,7 @@ void main() {
expect
(
widget
.
color
,
appBarTheme
.
backgroundColor
);
expect
(
widget
.
elevation
,
appBarTheme
.
elevation
);
expect
(
widget
.
shadowColor
,
appBarTheme
.
shadowColor
);
expect
(
widget
.
surfaceTintColor
,
appBarTheme
.
surfaceTintColor
);
expect
(
widget
.
shape
,
const
StadiumBorder
());
expect
(
iconTheme
.
data
,
appBarTheme
.
iconTheme
);
expect
(
actionsIconTheme
.
data
,
appBarTheme
.
actionsIconTheme
);
...
...
@@ -132,7 +151,8 @@ void main() {
const
SystemUiOverlayStyle
systemOverlayStyle
=
SystemUiOverlayStyle
.
light
;
const
Color
color
=
Colors
.
orange
;
const
double
elevation
=
3.0
;
const
Color
shadowColor
=
Colors
.
red
;
const
Color
shadowColor
=
Colors
.
purple
;
const
Color
surfaceTintColor
=
Colors
.
brown
;
const
ShapeBorder
shape
=
RoundedRectangleBorder
();
const
IconThemeData
iconThemeData
=
IconThemeData
(
color:
Colors
.
green
);
const
IconThemeData
actionsIconThemeData
=
IconThemeData
(
color:
Colors
.
lightBlue
);
...
...
@@ -151,6 +171,7 @@ void main() {
systemOverlayStyle:
systemOverlayStyle
,
elevation:
elevation
,
shadowColor:
shadowColor
,
surfaceTintColor:
surfaceTintColor
,
shape:
shape
,
iconTheme:
iconThemeData
,
actionsIconTheme:
actionsIconThemeData
,
...
...
@@ -174,6 +195,7 @@ void main() {
expect
(
widget
.
color
,
color
);
expect
(
widget
.
elevation
,
elevation
);
expect
(
widget
.
shadowColor
,
shadowColor
);
expect
(
widget
.
surfaceTintColor
,
surfaceTintColor
);
expect
(
widget
.
shape
,
shape
);
expect
(
iconTheme
.
data
,
iconThemeData
);
expect
(
actionsIconTheme
.
data
,
actionsIconThemeData
);
...
...
@@ -228,6 +250,7 @@ void main() {
expect
(
widget
.
color
,
appBarTheme
.
backgroundColor
);
expect
(
widget
.
elevation
,
appBarTheme
.
elevation
);
expect
(
widget
.
shadowColor
,
appBarTheme
.
shadowColor
);
expect
(
widget
.
surfaceTintColor
,
appBarTheme
.
surfaceTintColor
);
expect
(
iconTheme
.
data
,
appBarTheme
.
iconTheme
);
expect
(
actionsIconTheme
.
data
,
appBarTheme
.
actionsIconTheme
);
expect
(
actionIconText
.
text
.
style
!.
color
,
appBarTheme
.
actionsIconTheme
!.
color
);
...
...
@@ -235,15 +258,13 @@ void main() {
});
testWidgets
(
'ThemeData colorScheme is used when no AppBarTheme is set'
,
(
WidgetTester
tester
)
async
{
late
ThemeData
theme
;
final
ThemeData
lightTheme
=
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
light
());
final
ThemeData
darkTheme
=
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
dark
());
Widget
buildFrame
(
ThemeData
appTheme
)
{
return
MaterialApp
(
theme:
appTheme
,
home:
Builder
(
builder:
(
BuildContext
context
)
{
// This ThemeData has been localized with ThemeData.localize. The
// appTheme parameter has not, so its textTheme is incomplete.
theme
=
Theme
.
of
(
context
);
return
Scaffold
(
appBar:
AppBar
(
actions:
<
Widget
>[
...
...
@@ -256,15 +277,74 @@ void main() {
);
}
if
(
lightTheme
.
useMaterial3
)
{
// M3 AppBar defaults for light themes:
// - elevation: 0
// - shadow color: null
// - surface tint color: ColorScheme.surfaceTint
// - background color: ColorScheme.surface
// - foreground color: ColorScheme.onSurface
// - actions text: style bodyText2, foreground color
// - status bar brightness: light (based on color scheme brightness)
{
await
tester
.
pumpWidget
(
buildFrame
(
lightTheme
));
final
Material
widget
=
_getAppBarMaterial
(
tester
);
final
IconTheme
iconTheme
=
_getAppBarIconTheme
(
tester
);
final
IconTheme
actionsIconTheme
=
_getAppBarActionsIconTheme
(
tester
);
final
RichText
actionIconText
=
_getAppBarIconRichText
(
tester
);
final
DefaultTextStyle
text
=
_getAppBarText
(
tester
);
expect
(
SystemChrome
.
latestStyle
!.
statusBarBrightness
,
Brightness
.
light
);
expect
(
widget
.
color
,
lightTheme
.
colorScheme
.
surface
);
expect
(
widget
.
elevation
,
0
);
expect
(
widget
.
shadowColor
,
null
);
expect
(
widget
.
surfaceTintColor
,
lightTheme
.
colorScheme
.
surfaceTint
);
expect
(
iconTheme
.
data
.
color
,
lightTheme
.
colorScheme
.
onSurface
);
expect
(
actionsIconTheme
.
data
.
color
,
lightTheme
.
colorScheme
.
onSurface
);
expect
(
actionIconText
.
text
.
style
!.
color
,
lightTheme
.
colorScheme
.
onSurface
);
expect
(
text
.
style
,
Typography
.
material2021
().
englishLike
.
bodyText2
!.
merge
(
Typography
.
material2021
().
black
.
bodyText2
).
copyWith
(
color:
lightTheme
.
colorScheme
.
onSurface
));
}
// M3 AppBar defaults for dark themes:
// - elevation: 0
// - shadow color: null
// - surface tint color: ColorScheme.surfaceTint
// - background color: ColorScheme.surface
// - foreground color: ColorScheme.onSurface
// - actions text: style bodyText2, foreground color
// - status bar brightness: dark (based on background color)
{
await
tester
.
pumpWidget
(
buildFrame
(
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
dark
())));
await
tester
.
pumpAndSettle
();
// Theme change animation
final
Material
widget
=
_getAppBarMaterial
(
tester
);
final
IconTheme
iconTheme
=
_getAppBarIconTheme
(
tester
);
final
IconTheme
actionsIconTheme
=
_getAppBarActionsIconTheme
(
tester
);
final
RichText
actionIconText
=
_getAppBarIconRichText
(
tester
);
final
DefaultTextStyle
text
=
_getAppBarText
(
tester
);
expect
(
SystemChrome
.
latestStyle
!.
statusBarBrightness
,
Brightness
.
dark
);
expect
(
widget
.
color
,
darkTheme
.
colorScheme
.
surface
);
expect
(
widget
.
elevation
,
0
);
expect
(
widget
.
shadowColor
,
null
);
expect
(
widget
.
surfaceTintColor
,
darkTheme
.
colorScheme
.
surfaceTint
);
expect
(
iconTheme
.
data
.
color
,
darkTheme
.
colorScheme
.
onSurface
);
expect
(
actionsIconTheme
.
data
.
color
,
darkTheme
.
colorScheme
.
onSurface
);
expect
(
actionIconText
.
text
.
style
!.
color
,
darkTheme
.
colorScheme
.
onSurface
);
expect
(
text
.
style
,
Typography
.
material2021
().
englishLike
.
bodyText2
!.
merge
(
Typography
.
material2021
().
black
.
bodyText2
).
copyWith
(
color:
darkTheme
.
colorScheme
.
onSurface
));
}
}
else
{
// AppBar defaults for light themes:
// - elevation: 4
// - shadow color: black
// - surface tint color: null
// - background color: ColorScheme.primary
// - foreground color: ColorScheme.onPrimary
// - actions text: style bodyText2, foreground color
// - status bar brightness: light (based on color scheme brightness)
{
await
tester
.
pumpWidget
(
buildFrame
(
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
light
())
));
await
tester
.
pumpWidget
(
buildFrame
(
lightTheme
));
final
Material
widget
=
_getAppBarMaterial
(
tester
);
final
IconTheme
iconTheme
=
_getAppBarIconTheme
(
tester
);
...
...
@@ -273,24 +353,26 @@ void main() {
final
DefaultTextStyle
text
=
_getAppBarText
(
tester
);
expect
(
SystemChrome
.
latestStyle
!.
statusBarBrightness
,
SystemUiOverlayStyle
.
light
.
statusBarBrightness
);
expect
(
widget
.
color
,
t
heme
.
colorScheme
.
primary
);
expect
(
widget
.
color
,
lightT
heme
.
colorScheme
.
primary
);
expect
(
widget
.
elevation
,
4.0
);
expect
(
widget
.
shadowColor
,
Colors
.
black
);
expect
(
iconTheme
.
data
.
color
,
theme
.
colorScheme
.
onPrimary
);
expect
(
actionsIconTheme
.
data
.
color
,
theme
.
colorScheme
.
onPrimary
);
expect
(
actionIconText
.
text
.
style
!.
color
,
theme
.
colorScheme
.
onPrimary
);
expect
(
text
.
style
.
compareTo
(
theme
.
textTheme
.
bodyText2
!.
copyWith
(
color:
theme
.
colorScheme
.
onPrimary
)),
RenderComparison
.
identical
);
expect
(
widget
.
surfaceTintColor
,
null
);
expect
(
iconTheme
.
data
.
color
,
lightTheme
.
colorScheme
.
onPrimary
);
expect
(
actionsIconTheme
.
data
.
color
,
lightTheme
.
colorScheme
.
onPrimary
);
expect
(
actionIconText
.
text
.
style
!.
color
,
lightTheme
.
colorScheme
.
onPrimary
);
expect
(
text
.
style
,
Typography
.
material2014
().
englishLike
.
bodyText2
!.
merge
(
Typography
.
material2014
().
black
.
bodyText2
).
copyWith
(
color:
lightTheme
.
colorScheme
.
onPrimary
));
}
// AppBar defaults for dark themes:
// - elevation: 4
// - shadow color: black
// - surface tint color: null
// - background color: ColorScheme.surface
// - foreground color: ColorScheme.onSurface
// - actions text: style bodyText2, foreground color
// - status bar brightness: dark (based on background color)
{
await
tester
.
pumpWidget
(
buildFrame
(
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
dark
())
));
await
tester
.
pumpWidget
(
buildFrame
(
darkTheme
));
await
tester
.
pumpAndSettle
();
// Theme change animation
final
Material
widget
=
_getAppBarMaterial
(
tester
);
...
...
@@ -300,13 +382,15 @@ void main() {
final
DefaultTextStyle
text
=
_getAppBarText
(
tester
);
expect
(
SystemChrome
.
latestStyle
!.
statusBarBrightness
,
SystemUiOverlayStyle
.
light
.
statusBarBrightness
);
expect
(
widget
.
color
,
t
heme
.
colorScheme
.
surface
);
expect
(
widget
.
color
,
darkT
heme
.
colorScheme
.
surface
);
expect
(
widget
.
elevation
,
4.0
);
expect
(
widget
.
shadowColor
,
Colors
.
black
);
expect
(
iconTheme
.
data
.
color
,
theme
.
colorScheme
.
onSurface
);
expect
(
actionsIconTheme
.
data
.
color
,
theme
.
colorScheme
.
onSurface
);
expect
(
actionIconText
.
text
.
style
!.
color
,
theme
.
colorScheme
.
onSurface
);
expect
(
text
.
style
.
compareTo
(
theme
.
textTheme
.
bodyText2
!.
copyWith
(
color:
theme
.
colorScheme
.
onSurface
)),
RenderComparison
.
identical
);
expect
(
widget
.
surfaceTintColor
,
null
);
expect
(
iconTheme
.
data
.
color
,
darkTheme
.
colorScheme
.
onSurface
);
expect
(
actionsIconTheme
.
data
.
color
,
darkTheme
.
colorScheme
.
onSurface
);
expect
(
actionIconText
.
text
.
style
!.
color
,
darkTheme
.
colorScheme
.
onSurface
);
expect
(
text
.
style
,
Typography
.
material2014
().
englishLike
.
bodyText2
!.
merge
(
Typography
.
material2014
().
black
.
bodyText2
).
copyWith
(
color:
darkTheme
.
colorScheme
.
onSurface
));
}
}
});
...
...
@@ -315,7 +399,7 @@ void main() {
Widget
buildFrame
({
Color
?
appIconColor
,
Color
?
appBarIconColor
})
{
return
MaterialApp
(
theme:
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
light
()),
theme:
ThemeData
.
from
(
useMaterial3:
false
,
colorScheme:
const
ColorScheme
.
light
()),
home:
IconTheme
(
data:
IconThemeData
(
color:
appIconColor
),
child:
Builder
(
...
...
@@ -408,6 +492,22 @@ void main() {
expect
(
appBar
.
shadowColor
,
Colors
.
yellow
);
});
testWidgets
(
'AppBar.surfaceTintColor takes priority over AppBarTheme.surfaceTintColor'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
(
appBarTheme:
const
AppBarTheme
(
surfaceTintColor:
Colors
.
red
)),
home:
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'Title'
),
surfaceTintColor:
Colors
.
yellow
,
),
),
));
final
AppBar
appBar
=
tester
.
widget
(
find
.
byType
(
AppBar
));
// The AppBar.surfaceTintColor should be used instead of AppBarTheme.surfaceTintColor.
expect
(
appBar
.
surfaceTintColor
,
Colors
.
yellow
);
});
testWidgets
(
'AppBar uses AppBarTheme.titleSpacing'
,
(
WidgetTester
tester
)
async
{
const
double
kTitleSpacing
=
10
;
await
tester
.
pumpWidget
(
MaterialApp
(
...
...
@@ -493,6 +593,7 @@ void main() {
backgroundColor:
Color
(
0xff000001
),
elevation:
8.0
,
shadowColor:
Color
(
0xff000002
),
surfaceTintColor:
Color
(
0xff000003
),
centerTitle:
true
,
titleSpacing:
40.0
,
).
debugFillProperties
(
builder
);
...
...
@@ -507,6 +608,7 @@ void main() {
'backgroundColor: Color(0xff000001)'
,
'elevation: 8.0'
,
'shadowColor: Color(0xff000002)'
,
'surfaceTintColor: Color(0xff000003)'
,
'centerTitle: true'
,
'titleSpacing: 40.0'
,
]);
...
...
@@ -524,6 +626,7 @@ AppBarTheme _appBarTheme() {
const
Color
backgroundColor
=
Colors
.
lightBlue
;
const
double
elevation
=
6.0
;
const
Color
shadowColor
=
Colors
.
red
;
const
Color
surfaceTintColor
=
Colors
.
green
;
const
IconThemeData
iconThemeData
=
IconThemeData
(
color:
Colors
.
black
);
const
IconThemeData
actionsIconThemeData
=
IconThemeData
(
color:
Colors
.
pink
);
return
const
AppBarTheme
(
...
...
@@ -532,6 +635,7 @@ AppBarTheme _appBarTheme() {
backgroundColor:
backgroundColor
,
elevation:
elevation
,
shadowColor:
shadowColor
,
surfaceTintColor:
surfaceTintColor
,
shape:
StadiumBorder
(),
iconTheme:
iconThemeData
,
toolbarHeight:
96
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment