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
2ab2ca2b
Unverified
Commit
2ab2ca2b
authored
Jan 13, 2022
by
Darren Austin
Committed by
GitHub
Jan 13, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate FloatingActionButton to Material 3 (#94486)
parent
20ff180a
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
536 additions
and
74 deletions
+536
-74
material-tokens.json
dev/tools/gen_defaults/data/material-tokens.json
+2
-2
floating_action_button.dart
...ages/flutter/lib/src/material/floating_action_button.dart
+176
-50
floating_action_button_theme.dart
...lutter/lib/src/material/floating_action_button_theme.dart
+10
-0
theme_data.dart
packages/flutter/lib/src/material/theme_data.dart
+4
-4
floating_action_button_test.dart
...es/flutter/test/material/floating_action_button_test.dart
+322
-18
floating_action_button_theme_test.dart
...tter/test/material/floating_action_button_theme_test.dart
+22
-0
No files found.
dev/tools/gen_defaults/data/material-tokens.json
View file @
2ab2ca2b
{
"version"
:
"v0.7
2
"
,
"date"
:
"202
1-12-16 00:27:25.239571
"
,
"version"
:
"v0.7
4
"
,
"date"
:
"202
2-01-06
"
,
"md.sys.color.light.on-tertiary"
:
"md.ref.palette.tertiary100"
,
"md.sys.color.light.on-secondary-container"
:
"md.ref.palette.secondary10"
,
"md.sys.color.light.on-secondary"
:
"md.ref.palette.secondary100"
,
...
...
packages/flutter/lib/src/material/floating_action_button.dart
View file @
2ab2ca2b
...
...
@@ -9,31 +9,14 @@ import 'package:flutter/rendering.dart';
import
'package:flutter/widgets.dart'
;
import
'button.dart'
;
import
'color_scheme.dart'
;
import
'floating_action_button_theme.dart'
;
import
'scaffold.dart'
;
import
'text_theme.dart'
;
import
'theme.dart'
;
import
'theme_data.dart'
;
import
'tooltip.dart'
;
const
BoxConstraints
_kSizeConstraints
=
BoxConstraints
.
tightFor
(
width:
56.0
,
height:
56.0
,
);
const
BoxConstraints
_kMiniSizeConstraints
=
BoxConstraints
.
tightFor
(
width:
40.0
,
height:
40.0
,
);
const
BoxConstraints
_kLargeSizeConstraints
=
BoxConstraints
.
tightFor
(
width:
96.0
,
height:
96.0
,
);
const
BoxConstraints
_kExtendedSizeConstraints
=
BoxConstraints
.
tightFor
(
height:
48.0
,
);
class
_DefaultHeroTag
{
const
_DefaultHeroTag
();
@override
...
...
@@ -508,82 +491,80 @@ class FloatingActionButton extends StatelessWidget {
final
Widget
?
_extendedLabel
;
static
const
double
_defaultElevation
=
6
;
static
const
double
_defaultFocusElevation
=
6
;
static
const
double
_defaultHoverElevation
=
8
;
static
const
double
_defaultHighlightElevation
=
12
;
static
const
ShapeBorder
_defaultShape
=
CircleBorder
();
static
const
ShapeBorder
_defaultExtendedShape
=
StadiumBorder
();
@override
Widget
build
(
BuildContext
context
)
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
FloatingActionButtonThemeData
floatingActionButtonTheme
=
theme
.
floatingActionButtonTheme
;
final
FloatingActionButtonThemeData
defaults
=
theme
.
useMaterial3
?
_M3Defaults
(
context
,
_floatingActionButtonType
,
child
!=
null
)
:
_M2Defaults
(
context
,
_floatingActionButtonType
,
child
!=
null
);
final
Color
foregroundColor
=
this
.
foregroundColor
??
floatingActionButtonTheme
.
foregroundColor
??
theme
.
colorScheme
.
onSecondary
;
??
defaults
.
foregroundColor
!
;
final
Color
backgroundColor
=
this
.
backgroundColor
??
floatingActionButtonTheme
.
backgroundColor
??
theme
.
colorScheme
.
secondary
;
??
defaults
.
backgroundColor
!
;
final
Color
focusColor
=
this
.
focusColor
??
floatingActionButtonTheme
.
focusColor
??
theme
.
focusColor
;
??
defaults
.
focusColor
!
;
final
Color
hoverColor
=
this
.
hoverColor
??
floatingActionButtonTheme
.
hoverColor
??
theme
.
hoverColor
;
??
defaults
.
hoverColor
!
;
final
Color
splashColor
=
this
.
splashColor
??
floatingActionButtonTheme
.
splashColor
??
theme
.
splashColor
;
??
defaults
.
splashColor
!
;
final
double
elevation
=
this
.
elevation
??
floatingActionButtonTheme
.
elevation
??
_defaultElevation
;
??
defaults
.
elevation
!
;
final
double
focusElevation
=
this
.
focusElevation
??
floatingActionButtonTheme
.
focusElevation
??
_defaultFocusElevation
;
??
defaults
.
focusElevation
!
;
final
double
hoverElevation
=
this
.
hoverElevation
??
floatingActionButtonTheme
.
hoverElevation
??
_defaultHoverElevation
;
??
defaults
.
hoverElevation
!
;
final
double
disabledElevation
=
this
.
disabledElevation
??
floatingActionButtonTheme
.
disabledElevation
??
defaults
.
disabledElevation
??
elevation
;
final
double
highlightElevation
=
this
.
highlightElevation
??
floatingActionButtonTheme
.
highlightElevation
??
_defaultHighlightElevation
;
??
defaults
.
highlightElevation
!
;
final
MaterialTapTargetSize
materialTapTargetSize
=
this
.
materialTapTargetSize
??
theme
.
materialTapTargetSize
;
final
bool
enableFeedback
=
this
.
enableFeedback
??
floatingActionButtonTheme
.
enableFeedback
??
true
;
??
floatingActionButtonTheme
.
enableFeedback
??
defaults
.
enableFeedback
!;
final
double
iconSize
=
floatingActionButtonTheme
.
iconSize
??
defaults
.
iconSize
!;
final
TextStyle
extendedTextStyle
=
(
this
.
extendedTextStyle
??
floatingActionButtonTheme
.
extendedTextStyle
??
theme
.
textTheme
.
button
!.
copyWith
(
letterSpacing:
1.2
)
).
copyWith
(
color:
foregroundColor
);
??
defaults
.
extendedTextStyle
!
).
copyWith
(
color:
foregroundColor
);
final
ShapeBorder
shape
=
this
.
shape
??
floatingActionButtonTheme
.
shape
??
(
isExtended
?
_defaultExtendedShape
:
_defaultShape
)
;
??
defaults
.
shape
!
;
BoxConstraints
sizeConstraints
;
Widget
?
resolvedChild
=
child
;
Widget
?
resolvedChild
=
child
!=
null
?
IconTheme
.
merge
(
data:
IconThemeData
(
size:
iconSize
),
child:
child
!,
)
:
child
;
switch
(
_floatingActionButtonType
)
{
case
_FloatingActionButtonType
.
regular
:
sizeConstraints
=
floatingActionButtonTheme
.
sizeConstraints
??
_kSizeConstraints
;
sizeConstraints
=
floatingActionButtonTheme
.
sizeConstraints
??
defaults
.
sizeConstraints
!
;
break
;
case
_FloatingActionButtonType
.
small
:
sizeConstraints
=
floatingActionButtonTheme
.
smallSizeConstraints
??
_kMiniSizeConstraints
;
sizeConstraints
=
floatingActionButtonTheme
.
smallSizeConstraints
??
defaults
.
smallSizeConstraints
!
;
break
;
case
_FloatingActionButtonType
.
large
:
sizeConstraints
=
floatingActionButtonTheme
.
largeSizeConstraints
??
_kLargeSizeConstraints
;
// The large FAB uses a larger icon.
resolvedChild
=
child
!=
null
?
IconTheme
.
merge
(
data:
const
IconThemeData
(
size:
36.0
),
child:
child
!,
)
:
child
;
sizeConstraints
=
floatingActionButtonTheme
.
largeSizeConstraints
??
defaults
.
largeSizeConstraints
!;
break
;
case
_FloatingActionButtonType
.
extended
:
sizeConstraints
=
floatingActionButtonTheme
.
extendedSizeConstraints
??
_kExtendedSizeConstraints
;
sizeConstraints
=
floatingActionButtonTheme
.
extendedSizeConstraints
??
defaults
.
extendedSizeConstraints
!
;
final
double
iconLabelSpacing
=
extendedIconLabelSpacing
??
floatingActionButtonTheme
.
extendedIconLabelSpacing
??
8.0
;
final
EdgeInsetsGeometry
padding
=
extendedPadding
??
floatingActionButtonTheme
.
extendedPadding
??
EdgeInsetsDirectional
.
only
(
start:
child
!=
null
&&
isExtended
?
16.0
:
20.0
,
end:
20.0
)
;
??
defaults
.
extendedPadding
!
;
resolvedChild
=
_ChildOverflowBox
(
child:
Padding
(
padding:
padding
,
...
...
@@ -730,3 +711,148 @@ class _RenderChildOverflowBox extends RenderAligningShiftedBox {
}
}
}
// Generate a FloatingActionButtonThemeData that represents
// the M2 default values. This was generated by hand from the
// previous hand coded defaults for M2. It uses get method overrides
// instead of properties to avoid computing values that we may not
// need upfront.
class
_M2Defaults
extends
FloatingActionButtonThemeData
{
_M2Defaults
(
BuildContext
context
,
this
.
type
,
this
.
hasChild
)
:
_theme
=
Theme
.
of
(
context
),
_colors
=
Theme
.
of
(
context
).
colorScheme
;
final
_FloatingActionButtonType
type
;
final
bool
hasChild
;
final
ThemeData
_theme
;
final
ColorScheme
_colors
;
bool
get
_isExtended
=>
type
==
_FloatingActionButtonType
.
extended
;
bool
get
_isLarge
=>
type
==
_FloatingActionButtonType
.
large
;
@override
Color
?
get
foregroundColor
=>
_colors
.
onSecondary
;
@override
Color
?
get
backgroundColor
=>
_colors
.
secondary
;
@override
Color
?
get
focusColor
=>
_theme
.
focusColor
;
@override
Color
?
get
hoverColor
=>
_theme
.
hoverColor
;
@override
Color
?
get
splashColor
=>
_theme
.
splashColor
;
@override
double
?
get
elevation
=>
6
;
@override
double
?
get
focusElevation
=>
6
;
@override
double
?
get
hoverElevation
=>
8
;
@override
double
?
get
highlightElevation
=>
12
;
@override
ShapeBorder
?
get
shape
=>
_isExtended
?
const
StadiumBorder
()
:
const
CircleBorder
();
@override
bool
?
get
enableFeedback
=>
true
;
@override
double
?
get
iconSize
=>
_isLarge
?
36.0
:
24.0
;
@override
BoxConstraints
?
get
sizeConstraints
=>
const
BoxConstraints
.
tightFor
(
width:
56.0
,
height:
56.0
,
);
@override
BoxConstraints
?
get
smallSizeConstraints
=>
const
BoxConstraints
.
tightFor
(
width:
40.0
,
height:
40.0
,
);
@override
BoxConstraints
?
get
largeSizeConstraints
=>
const
BoxConstraints
.
tightFor
(
width:
96.0
,
height:
96.0
,
);
@override
BoxConstraints
?
get
extendedSizeConstraints
=>
const
BoxConstraints
.
tightFor
(
height:
48.0
,
);
@override
double
?
get
extendedIconLabelSpacing
=>
8.0
;
@override
EdgeInsetsGeometry
?
get
extendedPadding
=>
EdgeInsetsDirectional
.
only
(
start:
hasChild
&&
_isExtended
?
16.0
:
20.0
,
end:
20.0
);
@override
TextStyle
?
get
extendedTextStyle
=>
_theme
.
textTheme
.
button
!.
copyWith
(
letterSpacing:
1.2
);
}
// 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.74, 2022-01-06
class
_M3Defaults
extends
FloatingActionButtonThemeData
{
_M3Defaults
(
this
.
context
,
this
.
type
,
this
.
hasChild
)
:
_colors
=
Theme
.
of
(
context
).
colorScheme
,
_textTheme
=
Theme
.
of
(
context
).
textTheme
;
final
BuildContext
context
;
final
_FloatingActionButtonType
type
;
final
bool
hasChild
;
final
ColorScheme
_colors
;
final
TextTheme
_textTheme
;
bool
get
_isExtended
=>
type
==
_FloatingActionButtonType
.
extended
;
@override
Color
?
get
foregroundColor
=>
_colors
.
onPrimaryContainer
;
@override
Color
?
get
backgroundColor
=>
_colors
.
primaryContainer
;
@override
Color
?
get
splashColor
=>
_colors
.
onPrimaryContainer
.
withOpacity
(
0.12
);
@override
double
get
elevation
=>
6.0
;
@override
Color
?
get
focusColor
=>
_colors
.
onPrimaryContainer
.
withOpacity
(
0.12
);
@override
double
get
focusElevation
=>
6.0
;
@override
Color
?
get
hoverColor
=>
_colors
.
onPrimaryContainer
.
withOpacity
(
0.08
);
@override
double
get
hoverElevation
=>
8.0
;
@override
double
get
highlightElevation
=>
6.0
;
@override
ShapeBorder
?
get
shape
{
switch
(
type
)
{
case
_FloatingActionButtonType
.
regular
:
return
const
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
16.0
)));
case
_FloatingActionButtonType
.
small
:
return
const
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
12.0
)));
case
_FloatingActionButtonType
.
large
:
return
const
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
28.0
)));
case
_FloatingActionButtonType
.
extended
:
return
const
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
16.0
)));
}
}
@override
bool
?
get
enableFeedback
=>
true
;
@override
double
?
get
iconSize
{
switch
(
type
)
{
case
_FloatingActionButtonType
.
regular
:
return
24.0
;
case
_FloatingActionButtonType
.
small
:
return
24.0
;
case
_FloatingActionButtonType
.
large
:
return
36.0
;
case
_FloatingActionButtonType
.
extended
:
return
24.0
;
}
}
@override
BoxConstraints
?
get
sizeConstraints
=>
const
BoxConstraints
.
tightFor
(
width:
56.0
,
height:
56.0
,
);
@override
BoxConstraints
?
get
smallSizeConstraints
=>
const
BoxConstraints
.
tightFor
(
width:
40.0
,
height:
40.0
,
);
@override
BoxConstraints
?
get
largeSizeConstraints
=>
const
BoxConstraints
.
tightFor
(
width:
96.0
,
height:
96.0
,
);
@override
BoxConstraints
?
get
extendedSizeConstraints
=>
const
BoxConstraints
.
tightFor
(
height:
56.0
,
);
@override
double
?
get
extendedIconLabelSpacing
=>
8.0
;
@override
EdgeInsetsGeometry
?
get
extendedPadding
=>
EdgeInsetsDirectional
.
only
(
start:
hasChild
&&
_isExtended
?
16.0
:
20.0
,
end:
20.0
);
@override
TextStyle
?
get
extendedTextStyle
=>
_textTheme
.
labelLarge
;
}
// END GENERATED TOKEN PROPERTIES
packages/flutter/lib/src/material/floating_action_button_theme.dart
View file @
2ab2ca2b
...
...
@@ -43,6 +43,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
this
.
highlightElevation
,
this
.
shape
,
this
.
enableFeedback
,
this
.
iconSize
,
this
.
sizeConstraints
,
this
.
smallSizeConstraints
,
this
.
largeSizeConstraints
,
...
...
@@ -103,6 +104,9 @@ class FloatingActionButtonThemeData with Diagnosticable {
/// ignored.
final
bool
?
enableFeedback
;
/// Overrides the default icon size for the [FloatingActionButton];
final
double
?
iconSize
;
/// Overrides the default size constraints for the [FloatingActionButton].
final
BoxConstraints
?
sizeConstraints
;
...
...
@@ -140,6 +144,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
double
?
highlightElevation
,
ShapeBorder
?
shape
,
bool
?
enableFeedback
,
double
?
iconSize
,
BoxConstraints
?
sizeConstraints
,
BoxConstraints
?
smallSizeConstraints
,
BoxConstraints
?
largeSizeConstraints
,
...
...
@@ -161,6 +166,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
highlightElevation:
highlightElevation
??
this
.
highlightElevation
,
shape:
shape
??
this
.
shape
,
enableFeedback:
enableFeedback
??
this
.
enableFeedback
,
iconSize:
iconSize
??
this
.
iconSize
,
sizeConstraints:
sizeConstraints
??
this
.
sizeConstraints
,
smallSizeConstraints:
smallSizeConstraints
??
this
.
smallSizeConstraints
,
largeSizeConstraints:
largeSizeConstraints
??
this
.
largeSizeConstraints
,
...
...
@@ -193,6 +199,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
highlightElevation:
lerpDouble
(
a
?.
highlightElevation
,
b
?.
highlightElevation
,
t
),
shape:
ShapeBorder
.
lerp
(
a
?.
shape
,
b
?.
shape
,
t
),
enableFeedback:
t
<
0.5
?
a
?.
enableFeedback
:
b
?.
enableFeedback
,
iconSize:
lerpDouble
(
a
?.
iconSize
,
b
?.
iconSize
,
t
),
sizeConstraints:
BoxConstraints
.
lerp
(
a
?.
sizeConstraints
,
b
?.
sizeConstraints
,
t
),
smallSizeConstraints:
BoxConstraints
.
lerp
(
a
?.
smallSizeConstraints
,
b
?.
smallSizeConstraints
,
t
),
largeSizeConstraints:
BoxConstraints
.
lerp
(
a
?.
largeSizeConstraints
,
b
?.
largeSizeConstraints
,
t
),
...
...
@@ -218,6 +225,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
highlightElevation
,
shape
,
enableFeedback
,
iconSize
,
sizeConstraints
,
smallSizeConstraints
,
largeSizeConstraints
,
...
...
@@ -247,6 +255,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
&&
other
.
highlightElevation
==
highlightElevation
&&
other
.
shape
==
shape
&&
other
.
enableFeedback
==
enableFeedback
&&
other
.
iconSize
==
iconSize
&&
other
.
sizeConstraints
==
sizeConstraints
&&
other
.
smallSizeConstraints
==
smallSizeConstraints
&&
other
.
largeSizeConstraints
==
largeSizeConstraints
...
...
@@ -272,6 +281,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
properties
.
add
(
DoubleProperty
(
'highlightElevation'
,
highlightElevation
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
ShapeBorder
>(
'shape'
,
shape
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'enableFeedback'
,
enableFeedback
,
defaultValue:
null
));
properties
.
add
(
DoubleProperty
(
'iconSize'
,
iconSize
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
BoxConstraints
>(
'sizeConstraints'
,
sizeConstraints
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
BoxConstraints
>(
'smallSizeConstraints'
,
smallSizeConstraints
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
BoxConstraints
>(
'largeSizeConstraints'
,
largeSizeConstraints
,
defaultValue:
null
));
...
...
packages/flutter/lib/src/material/theme_data.dart
View file @
2ab2ca2b
...
...
@@ -1134,10 +1134,6 @@ class ThemeData with Diagnosticable {
/// start using new colors, typography and other features of Material 3.
/// If false, they will use the Material 2 look and feel.
///
/// Currently no components have been migrated to support Material 3.
/// As they are updated to include Material 3 support this documentation
/// will be modified to indicate exactly what widgets this flag will affect.
///
/// During the migration to Material 3, turning this on may yield
/// inconsistent look and feel in your app. Some components will be migrated
/// before others and typography changes will be coming in stages.
...
...
@@ -1148,6 +1144,10 @@ class ThemeData with Diagnosticable {
/// all uses of it. Everything will use the Material 3 look and feel at
/// that point.
///
/// Components that have been migrated to Material 3 are:
///
/// * [FloatingActionButton]
///
/// See also:
///
/// * [Material Design 3](https://m3.material.io/).
...
...
packages/flutter/test/material/floating_action_button_test.dart
View file @
2ab2ca2b
...
...
@@ -18,6 +18,10 @@ import '../widgets/semantics_tester.dart';
import
'feedback_tester.dart'
;
void
main
(
)
{
final
ThemeData
material3Theme
=
ThemeData
.
light
().
copyWith
(
useMaterial3:
true
);
final
ThemeData
material2Theme
=
ThemeData
.
light
().
copyWith
(
useMaterial3:
false
);
testWidgets
(
'Floating Action Button control test'
,
(
WidgetTester
tester
)
async
{
bool
didPressButton
=
false
;
await
tester
.
pumpWidget
(
...
...
@@ -171,6 +175,7 @@ void main() {
testWidgets
(
'Floating Action Button elevation when highlighted - effect'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material3Theme
,
home:
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
()
{
},
...
...
@@ -183,7 +188,7 @@ void main() {
await
tester
.
pump
();
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
12
.0
);
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6
.0
);
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
...
...
@@ -195,7 +200,7 @@ void main() {
),
);
await
tester
.
pump
();
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
12
.0
);
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6
.0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
20.0
);
await
gesture
.
up
();
...
...
@@ -277,6 +282,7 @@ void main() {
testWidgets
(
'Floating Action Button elevation when disabled while highlighted - effect'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material3Theme
,
home:
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
()
{
},
...
...
@@ -289,10 +295,11 @@ void main() {
await
tester
.
pump
();
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
12
.0
);
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6
.0
);
await
tester
.
pumpWidget
(
const
MaterialApp
(
home:
Scaffold
(
MaterialApp
(
theme:
material3Theme
,
home:
const
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
null
,
),
...
...
@@ -300,11 +307,12 @@ void main() {
),
);
await
tester
.
pump
();
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
12
.0
);
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6
.0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material3Theme
,
home:
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
()
{
},
...
...
@@ -323,6 +331,7 @@ void main() {
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material3Theme
,
home:
Scaffold
(
body:
FloatingActionButton
.
extended
(
label:
const
Text
(
'tooltip'
),
...
...
@@ -359,7 +368,7 @@ void main() {
await
gesture
.
down
(
center
);
await
tester
.
pump
();
// Start the splash and highlight animations.
await
tester
.
pump
(
const
Duration
(
milliseconds:
800
));
// Wait for splash and highlight to be well under way.
expect
(
getFABWidget
(
fabFinder
).
elevation
,
12
);
expect
(
getFABWidget
(
fabFinder
).
elevation
,
6
);
});
testWidgets
(
'FlatActionButton mini size is configurable by ThemeData.materialTapTargetSize'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -402,8 +411,9 @@ void main() {
testWidgets
(
'FloatingActionButton.isExtended'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
MaterialApp
(
home:
Scaffold
(
MaterialApp
(
theme:
material3Theme
,
home:
const
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
null
),
),
),
...
...
@@ -422,7 +432,10 @@ void main() {
}
expect
(
getFabWidget
().
isExtended
,
false
);
expect
(
getRawMaterialButtonWidget
().
shape
,
const
CircleBorder
());
expect
(
getRawMaterialButtonWidget
().
shape
,
const
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
16.0
)))
);
await
tester
.
pumpWidget
(
const
MaterialApp
(
...
...
@@ -440,13 +453,16 @@ void main() {
);
expect
(
getFabWidget
().
isExtended
,
true
);
expect
(
getRawMaterialButtonWidget
().
shape
,
const
StadiumBorder
());
expect
(
getRawMaterialButtonWidget
().
shape
,
const
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
16.0
)))
);
expect
(
find
.
text
(
'label'
),
findsOneWidget
);
expect
(
find
.
byType
(
Icon
),
findsOneWidget
);
// Verify that the widget's height is
48
and that its internal
// Verify that the widget's height is
56
and that its internal
/// horizontal layout is: 16 icon 8 label 20
expect
(
tester
.
getSize
(
fabFinder
).
height
,
48
.0
);
expect
(
tester
.
getSize
(
fabFinder
).
height
,
56
.0
);
final
double
fabLeft
=
tester
.
getTopLeft
(
fabFinder
).
dx
;
final
double
fabRight
=
tester
.
getTopRight
(
fabFinder
).
dx
;
...
...
@@ -479,8 +495,9 @@ void main() {
}
await
tester
.
pumpWidget
(
const
MaterialApp
(
home:
Scaffold
(
MaterialApp
(
theme:
material3Theme
,
home:
const
Scaffold
(
floatingActionButton:
FloatingActionButton
.
extended
(
label:
SizedBox
(
width:
100.0
,
...
...
@@ -493,13 +510,16 @@ void main() {
);
expect
(
getFabWidget
().
isExtended
,
true
);
expect
(
getRawMaterialButtonWidget
().
shape
,
const
StadiumBorder
());
expect
(
getRawMaterialButtonWidget
().
shape
,
const
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
16.0
)))
);
expect
(
find
.
text
(
'label'
),
findsOneWidget
);
expect
(
find
.
byType
(
Icon
),
findsNothing
);
// Verify that the widget's height is
48
and that its internal
// Verify that the widget's height is
56
and that its internal
/// horizontal layout is: 20 label 20
expect
(
tester
.
getSize
(
fabFinder
).
height
,
48
.0
);
expect
(
tester
.
getSize
(
fabFinder
).
height
,
56
.0
);
final
double
fabLeft
=
tester
.
getTopLeft
(
fabFinder
).
dx
;
final
double
fabRight
=
tester
.
getTopRight
(
fabFinder
).
dx
;
...
...
@@ -770,6 +790,7 @@ void main() {
final
GlobalKey
key
=
GlobalKey
();
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material3Theme
,
home:
Scaffold
(
body:
Center
(
child:
RepaintBoundary
(
...
...
@@ -1054,6 +1075,289 @@ void main() {
expect
(
rawMaterialButton
.
textStyle
,
style
.
copyWith
(
color:
const
Color
(
0xffffffff
)));
});
group
(
'Material 2'
,
()
{
// Tests that are only relevant for Material 2. Once ThemeData.useMaterial3
// is turned on by default, these tests can be removed.
testWidgets
(
'Floating Action Button elevation when highlighted - effect'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material2Theme
,
home:
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
()
{
},
),
),
),
);
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
final
TestGesture
gesture
=
await
tester
.
press
(
find
.
byType
(
PhysicalShape
));
await
tester
.
pump
();
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
12.0
);
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material2Theme
,
home:
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
()
{
},
highlightElevation:
20.0
,
),
),
),
);
await
tester
.
pump
();
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
12.0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
20.0
);
await
gesture
.
up
();
await
tester
.
pump
();
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
20.0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
});
testWidgets
(
'Floating Action Button elevation when disabled while highlighted - effect'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material2Theme
,
home:
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
()
{
},
),
),
),
);
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
await
tester
.
press
(
find
.
byType
(
PhysicalShape
));
await
tester
.
pump
();
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
12.0
);
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material2Theme
,
home:
const
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
null
,
),
),
),
);
await
tester
.
pump
();
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
12.0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material2Theme
,
home:
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
()
{
},
),
),
),
);
await
tester
.
pump
();
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
tester
.
widget
<
PhysicalShape
>(
find
.
byType
(
PhysicalShape
)).
elevation
,
6.0
);
});
testWidgets
(
'Floating Action Button states elevation'
,
(
WidgetTester
tester
)
async
{
final
FocusNode
focusNode
=
FocusNode
();
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material2Theme
,
home:
Scaffold
(
body:
FloatingActionButton
.
extended
(
label:
const
Text
(
'tooltip'
),
onPressed:
()
{},
focusNode:
focusNode
,
),
),
),
);
final
Finder
fabFinder
=
find
.
byType
(
PhysicalShape
);
PhysicalShape
getFABWidget
(
Finder
finder
)
=>
tester
.
widget
<
PhysicalShape
>(
finder
);
// Default, not disabled.
expect
(
getFABWidget
(
fabFinder
).
elevation
,
6
);
// Focused.
focusNode
.
requestFocus
();
await
tester
.
pumpAndSettle
();
expect
(
getFABWidget
(
fabFinder
).
elevation
,
6
);
// Hovered.
final
Offset
center
=
tester
.
getCenter
(
fabFinder
);
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
,
);
await
gesture
.
addPointer
();
addTearDown
(
gesture
.
removePointer
);
await
gesture
.
moveTo
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
getFABWidget
(
fabFinder
).
elevation
,
8
);
// Highlighted (pressed).
await
gesture
.
down
(
center
);
await
tester
.
pump
();
// Start the splash and highlight animations.
await
tester
.
pump
(
const
Duration
(
milliseconds:
800
));
// Wait for splash and highlight to be well under way.
expect
(
getFABWidget
(
fabFinder
).
elevation
,
12
);
});
testWidgets
(
'FloatingActionButton.isExtended'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material2Theme
,
home:
const
Scaffold
(
floatingActionButton:
FloatingActionButton
(
onPressed:
null
),
),
),
);
final
Finder
fabFinder
=
find
.
byType
(
FloatingActionButton
);
FloatingActionButton
getFabWidget
()
{
return
tester
.
widget
<
FloatingActionButton
>(
fabFinder
);
}
final
Finder
materialButtonFinder
=
find
.
byType
(
RawMaterialButton
);
RawMaterialButton
getRawMaterialButtonWidget
()
{
return
tester
.
widget
<
RawMaterialButton
>(
materialButtonFinder
);
}
expect
(
getFabWidget
().
isExtended
,
false
);
expect
(
getRawMaterialButtonWidget
().
shape
,
const
CircleBorder
());
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material2Theme
,
home:
const
Scaffold
(
floatingActionButton:
FloatingActionButton
.
extended
(
label:
SizedBox
(
width:
100.0
,
child:
Text
(
'label'
),
),
icon:
Icon
(
Icons
.
android
),
onPressed:
null
,
),
),
),
);
expect
(
getFabWidget
().
isExtended
,
true
);
expect
(
getRawMaterialButtonWidget
().
shape
,
const
StadiumBorder
());
expect
(
find
.
text
(
'label'
),
findsOneWidget
);
expect
(
find
.
byType
(
Icon
),
findsOneWidget
);
// Verify that the widget's height is 48 and that its internal
/// horizontal layout is: 16 icon 8 label 20
expect
(
tester
.
getSize
(
fabFinder
).
height
,
48.0
);
final
double
fabLeft
=
tester
.
getTopLeft
(
fabFinder
).
dx
;
final
double
fabRight
=
tester
.
getTopRight
(
fabFinder
).
dx
;
final
double
iconLeft
=
tester
.
getTopLeft
(
find
.
byType
(
Icon
)).
dx
;
final
double
iconRight
=
tester
.
getTopRight
(
find
.
byType
(
Icon
)).
dx
;
final
double
labelLeft
=
tester
.
getTopLeft
(
find
.
text
(
'label'
)).
dx
;
final
double
labelRight
=
tester
.
getTopRight
(
find
.
text
(
'label'
)).
dx
;
expect
(
iconLeft
-
fabLeft
,
16.0
);
expect
(
labelLeft
-
iconRight
,
8.0
);
expect
(
fabRight
-
labelRight
,
20.0
);
// The overall width of the button is:
// 168 = 16 + 24(icon) + 8 + 100(label) + 20
expect
(
tester
.
getSize
(
find
.
byType
(
Icon
)).
width
,
24.0
);
expect
(
tester
.
getSize
(
find
.
text
(
'label'
)).
width
,
100.0
);
expect
(
tester
.
getSize
(
fabFinder
).
width
,
168
);
});
testWidgets
(
'FloatingActionButton.isExtended (without icon)'
,
(
WidgetTester
tester
)
async
{
final
Finder
fabFinder
=
find
.
byType
(
FloatingActionButton
);
FloatingActionButton
getFabWidget
()
{
return
tester
.
widget
<
FloatingActionButton
>(
fabFinder
);
}
final
Finder
materialButtonFinder
=
find
.
byType
(
RawMaterialButton
);
RawMaterialButton
getRawMaterialButtonWidget
()
{
return
tester
.
widget
<
RawMaterialButton
>(
materialButtonFinder
);
}
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material2Theme
,
home:
const
Scaffold
(
floatingActionButton:
FloatingActionButton
.
extended
(
label:
SizedBox
(
width:
100.0
,
child:
Text
(
'label'
),
),
onPressed:
null
,
),
),
),
);
expect
(
getFabWidget
().
isExtended
,
true
);
expect
(
getRawMaterialButtonWidget
().
shape
,
const
StadiumBorder
());
expect
(
find
.
text
(
'label'
),
findsOneWidget
);
expect
(
find
.
byType
(
Icon
),
findsNothing
);
// Verify that the widget's height is 48 and that its internal
/// horizontal layout is: 20 label 20
expect
(
tester
.
getSize
(
fabFinder
).
height
,
48.0
);
final
double
fabLeft
=
tester
.
getTopLeft
(
fabFinder
).
dx
;
final
double
fabRight
=
tester
.
getTopRight
(
fabFinder
).
dx
;
final
double
labelLeft
=
tester
.
getTopLeft
(
find
.
text
(
'label'
)).
dx
;
final
double
labelRight
=
tester
.
getTopRight
(
find
.
text
(
'label'
)).
dx
;
expect
(
labelLeft
-
fabLeft
,
20.0
);
expect
(
fabRight
-
labelRight
,
20.0
);
// The overall width of the button is:
// 140 = 20 + 100(label) + 20
expect
(
tester
.
getSize
(
find
.
text
(
'label'
)).
width
,
100.0
);
expect
(
tester
.
getSize
(
fabFinder
).
width
,
140
);
});
// This test prevents https://github.com/flutter/flutter/issues/20483
testWidgets
(
'Floating Action Button clips ink splash and highlight'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
key
=
GlobalKey
();
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
material2Theme
,
home:
Scaffold
(
body:
Center
(
child:
RepaintBoundary
(
key:
key
,
child:
FloatingActionButton
(
onPressed:
()
{
},
child:
const
Icon
(
Icons
.
add
),
),
),
),
),
),
);
await
tester
.
press
(
find
.
byKey
(
key
));
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
milliseconds:
1000
));
await
expectLater
(
find
.
byKey
(
key
),
matchesGoldenFile
(
'floating_action_button_test_m2.clip.png'
),
);
});
});
group
(
'feedback'
,
()
{
late
FeedbackTester
feedback
;
...
...
packages/flutter/test/material/floating_action_button_theme_test.dart
View file @
2ab2ca2b
...
...
@@ -33,6 +33,8 @@ void main() {
expect
(
_getRawMaterialButton
(
tester
).
shape
,
const
CircleBorder
());
expect
(
_getRawMaterialButton
(
tester
).
splashColor
,
ThemeData
().
splashColor
);
expect
(
_getRawMaterialButton
(
tester
).
constraints
,
const
BoxConstraints
.
tightFor
(
width:
56.0
,
height:
56.0
));
expect
(
_getIconSize
(
tester
).
width
,
24.0
);
expect
(
_getIconSize
(
tester
).
height
,
24.0
);
});
testWidgets
(
'FloatingActionButtonThemeData values are used when no FloatingActionButton properties are specified'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -138,6 +140,7 @@ void main() {
testWidgets
(
'FloatingActionButton.small uses custom constraints when specified in the theme'
,
(
WidgetTester
tester
)
async
{
const
BoxConstraints
constraints
=
BoxConstraints
.
tightFor
(
width:
100.0
,
height:
100.0
);
const
double
iconSize
=
24.0
;
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
().
copyWith
(
...
...
@@ -154,10 +157,13 @@ void main() {
));
expect
(
_getRawMaterialButton
(
tester
).
constraints
,
constraints
);
expect
(
_getIconSize
(
tester
).
width
,
iconSize
);
expect
(
_getIconSize
(
tester
).
height
,
iconSize
);
});
testWidgets
(
'FloatingActionButton.large uses custom constraints when specified in the theme'
,
(
WidgetTester
tester
)
async
{
const
BoxConstraints
constraints
=
BoxConstraints
.
tightFor
(
width:
100.0
,
height:
100.0
);
const
double
iconSize
=
36.0
;
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
().
copyWith
(
...
...
@@ -174,6 +180,8 @@ void main() {
));
expect
(
_getRawMaterialButton
(
tester
).
constraints
,
constraints
);
expect
(
_getIconSize
(
tester
).
width
,
iconSize
);
expect
(
_getIconSize
(
tester
).
height
,
iconSize
);
});
testWidgets
(
'FloatingActionButton.extended uses custom properties when specified in the theme'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -271,6 +279,7 @@ void main() {
highlightElevation:
43
,
shape:
BeveledRectangleBorder
(),
enableFeedback:
true
,
iconSize:
42
,
sizeConstraints:
BoxConstraints
.
tightFor
(
width:
100.0
,
height:
100.0
),
smallSizeConstraints:
BoxConstraints
.
tightFor
(
width:
101.0
,
height:
101.0
),
largeSizeConstraints:
BoxConstraints
.
tightFor
(
width:
102.0
,
height:
102.0
),
...
...
@@ -298,6 +307,7 @@ void main() {
'highlightElevation: 43.0'
,
'shape: BeveledRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)'
,
'enableFeedback: true'
,
'iconSize: 42.0'
,
'sizeConstraints: BoxConstraints(w=100.0, h=100.0)'
,
'smallSizeConstraints: BoxConstraints(w=101.0, h=101.0)'
,
'largeSizeConstraints: BoxConstraints(w=102.0, h=102.0)'
,
...
...
@@ -326,3 +336,15 @@ RichText _getRichText(WidgetTester tester) {
),
);
}
SizedBox
_getIconSize
(
WidgetTester
tester
)
{
return
tester
.
widget
<
SizedBox
>(
find
.
descendant
(
of:
find
.
descendant
(
of:
find
.
byType
(
FloatingActionButton
),
matching:
find
.
byType
(
Icon
),
),
matching:
find
.
byType
(
SizedBox
),
),
);
}
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