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
801a6a7e
Unverified
Commit
801a6a7e
authored
Feb 08, 2020
by
filaps
Committed by
GitHub
Feb 08, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix SnackBar clipping when it is floating due to FloatingActionButton positioning (#47616)
parent
92a335e4
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
406 additions
and
210 deletions
+406
-210
scaffold.dart
packages/flutter/lib/src/material/scaffold.dart
+7
-3
snack_bar_test.dart
packages/flutter/test/material/snack_bar_test.dart
+399
-207
No files found.
packages/flutter/lib/src/material/scaffold.dart
View file @
801a6a7e
...
...
@@ -547,9 +547,13 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
if
(
snackBarSize
==
Size
.
zero
)
{
snackBarSize
=
layoutChild
(
_ScaffoldSlot
.
snackBar
,
fullWidthConstraints
);
}
final
double
snackBarYOffsetBase
=
floatingActionButtonRect
!=
null
&&
isSnackBarFloating
?
floatingActionButtonRect
.
top
:
contentBottom
;
double
snackBarYOffsetBase
;
if
(
floatingActionButtonRect
.
size
!=
Size
.
zero
&&
isSnackBarFloating
)
snackBarYOffsetBase
=
floatingActionButtonRect
.
top
;
else
snackBarYOffsetBase
=
contentBottom
;
positionChild
(
_ScaffoldSlot
.
snackBar
,
Offset
(
0.0
,
snackBarYOffsetBase
-
snackBarSize
.
height
));
}
...
...
packages/flutter/test/material/snack_bar_test.dart
View file @
801a6a7e
...
...
@@ -470,58 +470,62 @@ void main() {
expect
(
snackBarBottomRight
.
dy
-
actionTextBottomRight
.
dy
,
17.0
+
40.0
);
// margin + bottom padding
},
skip:
isBrowser
);
testWidgets
(
'SnackBar is positioned above BottomNavigationBar'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
home:
MediaQuery
(
data:
const
MediaQueryData
(
padding:
EdgeInsets
.
only
(
left:
10.0
,
top:
20.0
,
right:
30.0
,
bottom:
40.0
,
),
),
child:
Scaffold
(
bottomNavigationBar:
BottomNavigationBar
(
items:
const
<
BottomNavigationBarItem
>[
BottomNavigationBarItem
(
icon:
Icon
(
Icons
.
favorite
),
title:
Text
(
'Animutation'
)),
BottomNavigationBarItem
(
icon:
Icon
(
Icons
.
block
),
title:
Text
(
'Zombo.com'
)),
],
testWidgets
(
'Custom padding between SnackBar and its contents when set to SnackBarBehavior.fixed'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
home:
MediaQuery
(
data:
const
MediaQueryData
(
padding:
EdgeInsets
.
only
(
left:
10.0
,
top:
20.0
,
right:
30.0
,
bottom:
40.0
,
),
),
body:
Builder
(
builder:
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
{
Scaffold
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
const
Text
(
'I am a snack bar.'
),
duration:
const
Duration
(
seconds:
2
),
action:
SnackBarAction
(
label:
'ACTION'
,
onPressed:
()
{
}),
));
},
child:
const
Text
(
'X'
),
);
}
child:
Scaffold
(
bottomNavigationBar:
BottomNavigationBar
(
items:
const
<
BottomNavigationBarItem
>[
BottomNavigationBarItem
(
icon:
Icon
(
Icons
.
favorite
),
title:
Text
(
'Animutation'
)),
BottomNavigationBarItem
(
icon:
Icon
(
Icons
.
block
),
title:
Text
(
'Zombo.com'
)),
],
),
body:
Builder
(
builder:
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
{
Scaffold
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
const
Text
(
'I am a snack bar.'
),
duration:
const
Duration
(
seconds:
2
),
action:
SnackBarAction
(
label:
'ACTION'
,
onPressed:
()
{}),
));
},
child:
const
Text
(
'X'
),
);
}
),
),
),
),
));
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pump
();
// start animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
750
));
// Animation last frame.
final
Offset
textBottomLeft
=
tester
.
getBottomLeft
(
find
.
text
(
'I am a snack bar.'
));
final
Offset
textBottomRight
=
tester
.
getBottomRight
(
find
.
text
(
'I am a snack bar.'
));
final
Offset
actionTextBottomLeft
=
tester
.
getBottomLeft
(
find
.
text
(
'ACTION'
));
final
Offset
actionTextBottomRight
=
tester
.
getBottomRight
(
find
.
text
(
'ACTION'
));
final
Offset
snackBarBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
snackBarBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
expect
(
textBottomLeft
.
dx
-
snackBarBottomLeft
.
dx
,
24.0
+
10.0
);
// margin + left padding
expect
(
snackBarBottomLeft
.
dy
-
textBottomLeft
.
dy
,
17.0
);
// margin (with no bottom padding)
expect
(
actionTextBottomLeft
.
dx
-
textBottomRight
.
dx
,
24.0
);
expect
(
snackBarBottomRight
.
dx
-
actionTextBottomRight
.
dx
,
24.0
+
30.0
);
// margin + right padding
expect
(
snackBarBottomRight
.
dy
-
actionTextBottomRight
.
dy
,
17.0
);
// margin (with no bottom padding)
},
skip:
isBrowser
);
));
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pump
();
// start animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
750
));
// Animation last frame.
final
Offset
textBottomLeft
=
tester
.
getBottomLeft
(
find
.
text
(
'I am a snack bar.'
));
final
Offset
textBottomRight
=
tester
.
getBottomRight
(
find
.
text
(
'I am a snack bar.'
));
final
Offset
actionTextBottomLeft
=
tester
.
getBottomLeft
(
find
.
text
(
'ACTION'
));
final
Offset
actionTextBottomRight
=
tester
.
getBottomRight
(
find
.
text
(
'ACTION'
));
final
Offset
snackBarBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
snackBarBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
expect
(
textBottomLeft
.
dx
-
snackBarBottomLeft
.
dx
,
24.0
+
10.0
);
// margin + left padding
expect
(
snackBarBottomLeft
.
dy
-
textBottomLeft
.
dy
,
17.0
);
// margin (with no bottom padding)
expect
(
actionTextBottomLeft
.
dx
-
textBottomRight
.
dx
,
24.0
);
expect
(
snackBarBottomRight
.
dx
-
actionTextBottomRight
.
dx
,
24.0
+
30.0
);
// margin + right padding
expect
(
snackBarBottomRight
.
dy
-
actionTextBottomRight
.
dy
,
17.0
);
// margin (with no bottom padding)
},
skip:
isBrowser
,
);
testWidgets
(
'SnackBar should push FloatingActionButton above'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
...
...
@@ -557,70 +561,28 @@ void main() {
),
));
final
Offset
floatingActionButtonOriginBottomCenter
=
tester
.
getCenter
(
find
.
byType
(
FloatingActionButton
));
// Get the Rect of the FAB to compare after the SnackBar appears.
final
Rect
originalFabRect
=
tester
.
getRect
(
find
.
byType
(
FloatingActionButton
));
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pump
();
// start animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
750
));
// Animation last frame.
final
Offset
snackBarTopCenter
=
tester
.
getCenter
(
find
.
byType
(
SnackBar
));
final
Offset
floatingActionButtonBottomCenter
=
tester
.
getCenter
(
find
.
byType
(
FloatingActionButton
));
final
Rect
fabRect
=
tester
.
getRect
(
find
.
byType
(
FloatingActionButton
));
expect
(
floatingActionButtonOriginBottomCenter
.
dy
>
floatingActionButtonBottomCenter
.
dy
,
true
);
expect
(
snackBarTopCenter
.
dy
>
floatingActionButtonBottomCenter
.
dy
,
true
);
});
// FAB should shift upwards after SnackBar appears.
expect
(
fabRect
.
center
.
dy
,
lessThan
(
originalFabRect
.
center
.
dy
));
testWidgets
(
'Floating SnackBar button text alignment'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
(
snackBarTheme:
const
SnackBarThemeData
(
behavior:
SnackBarBehavior
.
floating
,)
),
home:
MediaQuery
(
data:
const
MediaQueryData
(
padding:
EdgeInsets
.
only
(
left:
10.0
,
top:
20.0
,
right:
30.0
,
bottom:
40.0
,
),
),
child:
Scaffold
(
body:
Builder
(
builder:
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
{
Scaffold
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
const
Text
(
'I am a snack bar.'
),
duration:
const
Duration
(
seconds:
2
),
action:
SnackBarAction
(
label:
'ACTION'
,
onPressed:
()
{}),
));
},
child:
const
Text
(
'X'
),
);
}
),
),
),
));
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pump
();
// start animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
750
));
// Animation last frame.
final
Offset
snackBarTopRight
=
tester
.
getTopRight
(
find
.
byType
(
SnackBar
));
final
Offset
textBottomLeft
=
tester
.
getBottomLeft
(
find
.
text
(
'I am a snack bar.'
));
final
Offset
textBottomRight
=
tester
.
getBottomRight
(
find
.
text
(
'I am a snack bar.'
));
final
Offset
actionTextBottomLeft
=
tester
.
getBottomLeft
(
find
.
text
(
'ACTION'
));
final
Offset
actionTextBottomRight
=
tester
.
getBottomRight
(
find
.
text
(
'ACTION'
));
final
Offset
snackBarBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
snackBarBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
// FAB's surrounding padding is set to [kFloatingActionButtonMargin] in floating_action_button_location.dart by default.
const
int
defaultFabPadding
=
16
;
expect
(
textBottomLeft
.
dx
-
snackBarBottomLeft
.
dx
,
31.0
+
10.0
);
// margin + left padding
expect
(
snackBarBottomLeft
.
dy
-
textBottomLeft
.
dy
,
27.0
);
// margin (with no bottom padding)
expect
(
actionTextBottomLeft
.
dx
-
textBottomRight
.
dx
,
16.0
);
expect
(
snackBarBottomRight
.
dx
-
actionTextBottomRight
.
dx
,
31.0
+
30.0
);
// margin + right padding
expect
(
snackBarBottomRight
.
dy
-
actionTextBottomRight
.
dy
,
27.0
);
// margin (with no bottom padding)
},
skip:
isBrowser
);
// FAB should be positioned above the SnackBar by the default padding.
expect
(
fabRect
.
bottomRight
.
dy
,
snackBarTopRight
.
dy
-
defaultFabPadding
);
});
testWidgets
(
'Floating SnackBar
is positioned above BottomNavigationBar
'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Floating SnackBar
button text alignment
'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
(
snackBarTheme:
const
SnackBarThemeData
(
behavior:
SnackBarBehavior
.
floating
,)
...
...
@@ -635,12 +597,6 @@ void main() {
),
),
child:
Scaffold
(
bottomNavigationBar:
BottomNavigationBar
(
items:
const
<
BottomNavigationBarItem
>[
BottomNavigationBarItem
(
icon:
Icon
(
Icons
.
favorite
),
title:
Text
(
'Animutation'
)),
BottomNavigationBarItem
(
icon:
Icon
(
Icons
.
block
),
title:
Text
(
'Zombo.com'
)),
],
),
body:
Builder
(
builder:
(
BuildContext
context
)
{
return
GestureDetector
(
...
...
@@ -676,108 +632,65 @@ void main() {
expect
(
snackBarBottomRight
.
dy
-
actionTextBottomRight
.
dy
,
27.0
);
// margin (with no bottom padding)
},
skip:
isBrowser
);
testWidgets
(
'Floating SnackBar is positioned above FloatingActionButton'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
(
snackBarTheme:
const
SnackBarThemeData
(
behavior:
SnackBarBehavior
.
floating
,)
),
home:
MediaQuery
(
data:
const
MediaQueryData
(
padding:
EdgeInsets
.
only
(
left:
10.0
,
top:
20.0
,
right:
30.0
,
bottom:
40.0
,
),
testWidgets
(
'Custom padding between SnackBar and its contents when set to SnackBarBehavior.floating'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
(
snackBarTheme:
const
SnackBarThemeData
(
behavior:
SnackBarBehavior
.
floating
)
),
child:
Scaffold
(
floatingActionButton:
FloatingActionButton
(
child:
const
Icon
(
Icons
.
send
),
onPressed:
()
{},
home:
MediaQuery
(
data:
const
MediaQueryData
(
padding:
EdgeInsets
.
only
(
left:
10.0
,
top:
20.0
,
right:
30.0
,
bottom:
40.0
,
),
),
body:
Builder
(
builder:
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
{
Scaffold
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
const
Text
(
'I am a snack bar.'
),
duration:
const
Duration
(
seconds:
2
),
action:
SnackBarAction
(
label:
'ACTION'
,
onPressed:
()
{}),
));
},
child:
const
Text
(
'X'
),
);
}
child:
Scaffold
(
bottomNavigationBar:
BottomNavigationBar
(
items:
const
<
BottomNavigationBarItem
>[
BottomNavigationBarItem
(
icon:
Icon
(
Icons
.
favorite
),
title:
Text
(
'Animutation'
)),
BottomNavigationBarItem
(
icon:
Icon
(
Icons
.
block
),
title:
Text
(
'Zombo.com'
)),
],
),
body:
Builder
(
builder:
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
{
Scaffold
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
const
Text
(
'I am a snack bar.'
),
duration:
const
Duration
(
seconds:
2
),
action:
SnackBarAction
(
label:
'ACTION'
,
onPressed:
()
{}),
));
},
child:
const
Text
(
'X'
),
);
}
),
),
),
),
));
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pump
();
// start animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
750
));
// Animation last frame.
final
Offset
snackBarBottomCenter
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
floatingActionButtonTopCenter
=
tester
.
getTopLeft
(
find
.
byType
(
FloatingActionButton
));
// Since padding and margin is handled inside snackBarBox,
// the bottom offset of snackbar should equal with top offset of FAB
expect
(
snackBarBottomCenter
.
dy
==
floatingActionButtonTopCenter
.
dy
,
true
);
});
testWidgets
(
'SnackBar bottom padding is not consumed by viewInsets'
,
(
WidgetTester
tester
)
async
{
final
Widget
child
=
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Scaffold
(
resizeToAvoidBottomInset:
false
,
floatingActionButton:
FloatingActionButton
(
child:
const
Icon
(
Icons
.
send
),
onPressed:
()
{},
),
body:
Builder
(
builder:
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
{
Scaffold
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
const
Text
(
'I am a snack bar.'
),
duration:
const
Duration
(
seconds:
2
),
action:
SnackBarAction
(
label:
'ACTION'
,
onPressed:
()
{}),
),
);
},
child:
const
Text
(
'X'
),
);
}
),
));
await
tester
.
pumpWidget
(
MediaQuery
(
data:
const
MediaQueryData
(
padding:
EdgeInsets
.
only
(
bottom:
20.0
),
),
child:
child
,
),
);
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pumpAndSettle
();
// Show snackbar
final
Offset
initialPoint
=
tester
.
getCenter
(
find
.
byType
(
SnackBar
));
// Consume bottom padding - as if by the keyboard opening
await
tester
.
pumpWidget
(
MediaQuery
(
data:
const
MediaQueryData
(
padding:
EdgeInsets
.
zero
,
viewPadding:
EdgeInsets
.
only
(
bottom:
20
),
viewInsets:
EdgeInsets
.
only
(
bottom:
300
),
),
child:
child
,
),
);
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pumpAndSettle
();
final
Offset
finalPoint
=
tester
.
getCenter
(
find
.
byType
(
SnackBar
));
expect
(
initialPoint
,
finalPoint
);
});
));
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pump
();
// start animation
await
tester
.
pump
(
const
Duration
(
milliseconds:
750
));
// Animation last frame.
final
Offset
textBottomLeft
=
tester
.
getBottomLeft
(
find
.
text
(
'I am a snack bar.'
));
final
Offset
textBottomRight
=
tester
.
getBottomRight
(
find
.
text
(
'I am a snack bar.'
));
final
Offset
actionTextBottomLeft
=
tester
.
getBottomLeft
(
find
.
text
(
'ACTION'
));
final
Offset
actionTextBottomRight
=
tester
.
getBottomRight
(
find
.
text
(
'ACTION'
));
final
Offset
snackBarBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
snackBarBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
expect
(
textBottomLeft
.
dx
-
snackBarBottomLeft
.
dx
,
31.0
+
10.0
);
// margin + left padding
expect
(
snackBarBottomLeft
.
dy
-
textBottomLeft
.
dy
,
27.0
);
// margin (with no bottom padding)
expect
(
actionTextBottomLeft
.
dx
-
textBottomRight
.
dx
,
16.0
);
expect
(
snackBarBottomRight
.
dx
-
actionTextBottomRight
.
dx
,
31.0
+
30.0
);
// margin + right padding
expect
(
snackBarBottomRight
.
dy
-
actionTextBottomRight
.
dy
,
27.0
);
// margin (with no bottom padding)
},
skip:
isBrowser
,
);
testWidgets
(
'SnackBarClosedReason'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
<
ScaffoldState
>
scaffoldKey
=
GlobalKey
<
ScaffoldState
>();
...
...
@@ -1146,4 +1059,283 @@ void main() {
expect
(
find
.
text
(
'hello'
),
findsOneWidget
);
expect
(
called
,
1
);
});
group
(
'SnackBar position'
,
()
{
for
(
final
SnackBarBehavior
behavior
in
SnackBarBehavior
.
values
)
{
final
SnackBar
snackBar
=
SnackBar
(
content:
const
Text
(
'SnackBar text'
),
behavior:
behavior
,
);
testWidgets
(
'
$behavior
should align SnackBar with the bottom of Scaffold '
'when Scaffold has no other elements'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Container
(),
),
),
);
final
ScaffoldState
scaffoldState
=
tester
.
state
(
find
.
byType
(
Scaffold
));
scaffoldState
.
showSnackBar
(
snackBar
);
await
tester
.
pumpAndSettle
();
// Have the SnackBar fully animate out.
final
Offset
snackBarBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
final
Offset
scaffoldBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
Scaffold
));
expect
(
snackBarBottomRight
,
equals
(
scaffoldBottomRight
));
final
Offset
snackBarBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
scaffoldBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
Scaffold
));
expect
(
snackBarBottomLeft
,
equals
(
scaffoldBottomLeft
));
},
);
testWidgets
(
'
$behavior
should align SnackBar with the top of BottomNavigationBar '
'when Scaffold has no FloatingActionButton'
,
(
WidgetTester
tester
)
async
{
final
UniqueKey
boxKey
=
UniqueKey
();
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Container
(),
bottomNavigationBar:
SizedBox
(
key:
boxKey
,
width:
800
,
height:
60
),
),
),
);
final
ScaffoldState
scaffoldState
=
tester
.
state
(
find
.
byType
(
Scaffold
));
scaffoldState
.
showSnackBar
(
snackBar
);
await
tester
.
pumpAndSettle
();
// Have the SnackBar fully animate out.
final
Offset
snackBarBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
final
Offset
bottomNavigationBarTopRight
=
tester
.
getTopRight
(
find
.
byKey
(
boxKey
));
expect
(
snackBarBottomRight
,
equals
(
bottomNavigationBarTopRight
));
final
Offset
snackBarBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
bottomNavigationBarTopLeft
=
tester
.
getTopLeft
(
find
.
byKey
(
boxKey
));
expect
(
snackBarBottomLeft
,
equals
(
bottomNavigationBarTopLeft
));
},
);
testWidgets
(
'Padding of
$behavior
is not consumed by viewInsets'
,
(
WidgetTester
tester
)
async
{
final
Widget
child
=
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Scaffold
(
resizeToAvoidBottomInset:
false
,
floatingActionButton:
FloatingActionButton
(
child:
const
Icon
(
Icons
.
send
),
onPressed:
()
{},
),
body:
Builder
(
builder:
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
{
Scaffold
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
const
Text
(
'I am a snack bar.'
),
duration:
const
Duration
(
seconds:
2
),
action:
SnackBarAction
(
label:
'ACTION'
,
onPressed:
()
{}),
behavior:
behavior
,
),
);
},
child:
const
Text
(
'X'
),
);
},
),
),
);
await
tester
.
pumpWidget
(
MediaQuery
(
data:
const
MediaQueryData
(
padding:
EdgeInsets
.
only
(
bottom:
20.0
),
),
child:
child
,
),
);
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pumpAndSettle
();
// Show snackbar
final
Offset
initialBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
initialBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
// Consume bottom padding - as if by the keyboard opening
await
tester
.
pumpWidget
(
MediaQuery
(
data:
const
MediaQueryData
(
padding:
EdgeInsets
.
zero
,
viewPadding:
EdgeInsets
.
all
(
20
),
viewInsets:
EdgeInsets
.
all
(
100
),
),
child:
child
,
),
);
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pumpAndSettle
();
// Have the SnackBar fully animate out.
final
Offset
finalBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
finalBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
expect
(
initialBottomLeft
,
finalBottomLeft
);
expect
(
initialBottomRight
,
finalBottomRight
);
},
);
}
testWidgets
(
'
${SnackBarBehavior.fixed}
should align SnackBar with the bottom of Scaffold '
'when Scaffold has a FloatingActionButton'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Container
(),
floatingActionButton:
FloatingActionButton
(
onPressed:
()
{}),
),
),
);
final
ScaffoldState
scaffoldState
=
tester
.
state
(
find
.
byType
(
Scaffold
));
scaffoldState
.
showSnackBar
(
const
SnackBar
(
content:
Text
(
'Snackbar text'
),
behavior:
SnackBarBehavior
.
fixed
,
),
);
await
tester
.
pumpAndSettle
();
// Have the SnackBar fully animate out.
final
Offset
snackBarBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
final
Offset
scaffoldBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
Scaffold
));
expect
(
snackBarBottomRight
,
equals
(
scaffoldBottomRight
));
final
Offset
snackBarBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
scaffoldBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
Scaffold
));
expect
(
snackBarBottomLeft
,
equals
(
scaffoldBottomLeft
));
},
);
testWidgets
(
'
${SnackBarBehavior.floating}
should align SnackBar with the top of FloatingActionButton'
'when Scaffold has a FloatingActionButton'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
floatingActionButton:
FloatingActionButton
(
child:
const
Icon
(
Icons
.
send
),
onPressed:
()
{},
),
body:
Builder
(
builder:
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
{
Scaffold
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
const
Text
(
'I am a snack bar.'
),
duration:
const
Duration
(
seconds:
2
),
action:
SnackBarAction
(
label:
'ACTION'
,
onPressed:
()
{}),
behavior:
SnackBarBehavior
.
floating
,
));
},
child:
const
Text
(
'X'
),
);
},
),
),
));
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pumpAndSettle
();
// Have the SnackBar fully animate out.
final
Offset
snackBarBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
floatingActionButtonTopLeft
=
tester
.
getTopLeft
(
find
.
byType
(
FloatingActionButton
),
);
// Since padding between the SnackBar and the FAB is created by the SnackBar,
// the bottom offset of the SnackBar should be equal to the top offset of the FAB
expect
(
snackBarBottomLeft
.
dy
,
floatingActionButtonTopLeft
.
dy
);
},
);
testWidgets
(
'
${SnackBarBehavior.fixed}
should align SnackBar with the top of BottomNavigationBar '
'when Scaffold has a BottomNavigationBar and FloatingActionButton'
,
(
WidgetTester
tester
)
async
{
final
UniqueKey
boxKey
=
UniqueKey
();
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Container
(),
bottomNavigationBar:
SizedBox
(
key:
boxKey
,
width:
800
,
height:
60
),
floatingActionButton:
FloatingActionButton
(
onPressed:
()
{}),
),
),
);
final
ScaffoldState
scaffoldState
=
tester
.
state
(
find
.
byType
(
Scaffold
));
scaffoldState
.
showSnackBar
(
const
SnackBar
(
content:
Text
(
'SnackBar text'
),
behavior:
SnackBarBehavior
.
fixed
,
),
);
await
tester
.
pumpAndSettle
();
// Have the SnackBar fully animate out.
final
Offset
snackBarBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
final
Offset
bottomNavigationBarTopRight
=
tester
.
getTopRight
(
find
.
byKey
(
boxKey
));
expect
(
snackBarBottomRight
,
equals
(
bottomNavigationBarTopRight
));
final
Offset
snackBarBottomLeft
=
tester
.
getBottomLeft
(
find
.
byType
(
SnackBar
));
final
Offset
bottomNavigationBarTopLeft
=
tester
.
getTopLeft
(
find
.
byKey
(
boxKey
));
expect
(
snackBarBottomLeft
,
equals
(
bottomNavigationBarTopLeft
));
},
);
testWidgets
(
'
${SnackBarBehavior.floating}
should align SnackBar with the top of FloatingActionButton '
'when Scaffold has BottomNavigationBar and FloatingActionButton'
,
(
WidgetTester
tester
)
async
{
final
UniqueKey
boxKey
=
UniqueKey
();
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Container
(),
bottomNavigationBar:
SizedBox
(
key:
boxKey
,
width:
800
,
height:
60
),
floatingActionButton:
FloatingActionButton
(
onPressed:
()
{}),
),
),
);
final
ScaffoldState
scaffoldState
=
tester
.
state
(
find
.
byType
(
Scaffold
));
scaffoldState
.
showSnackBar
(
const
SnackBar
(
content:
Text
(
'SnackBar text'
),
behavior:
SnackBarBehavior
.
floating
,
),
);
await
tester
.
pumpAndSettle
();
// Have the SnackBar fully animate out.
final
Offset
snackBarBottomRight
=
tester
.
getBottomRight
(
find
.
byType
(
SnackBar
));
final
Offset
fabTopRight
=
tester
.
getTopRight
(
find
.
byType
(
FloatingActionButton
));
expect
(
snackBarBottomRight
.
dy
,
equals
(
fabTopRight
.
dy
));
},
);
});
}
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