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
fd7a72ee
Unverified
Commit
fd7a72ee
authored
Jun 26, 2020
by
Kate Lovett
Committed by
GitHub
Jun 26, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Ensure FloatingActionButtonLocations are always within safe interactive areas (#60248)
parent
a4fa61b4
Changes
3
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
788 additions
and
8 deletions
+788
-8
floating_action_button_location.dart
...ter/lib/src/material/floating_action_button_location.dart
+25
-7
scaffold.dart
packages/flutter/lib/src/material/scaffold.dart
+21
-0
floating_action_button_location_test.dart
...r/test/material/floating_action_button_location_test.dart
+742
-1
No files found.
packages/flutter/lib/src/material/floating_action_button_location.dart
View file @
fd7a72ee
...
@@ -413,15 +413,27 @@ abstract class StandardFabLocation extends FloatingActionButtonLocation {
...
@@ -413,15 +413,27 @@ abstract class StandardFabLocation extends FloatingActionButtonLocation {
}
}
/// Mixin for a "top" floating action button location, such as [FloatingActionButtonLocation.startTop].
/// Mixin for a "top" floating action button location, such as
/// [FloatingActionButtonLocation.startTop].
///
/// The [adjustment], typically [kMiniButtonOffsetAdjustment], is ignored in the
/// Y axis of "top" positions. For "top" positions, the X offset is adjusted to
/// move closer to the edge of the screen. This is so that a minified floating
/// action button appears to align with [CircleAvatar]s in the
/// [ListTile.leading] slot of a [ListTile] in a [ListView] in the
/// [Scaffold.body].
mixin
FabTopOffsetY
on
StandardFabLocation
{
mixin
FabTopOffsetY
on
StandardFabLocation
{
/// Calculates y-offset for [FloatingActionButtonLocation]s floating over
/// Calculates y-offset for [FloatingActionButtonLocation]s floating over
/// the transition between the [Scaffold.appBar] and the [Scaffold.body].
/// the transition between the [Scaffold.appBar] and the [Scaffold.body].
@override
@override
double
getOffsetY
(
ScaffoldPrelayoutGeometry
scaffoldGeometry
,
double
adjustment
)
{
double
getOffsetY
(
ScaffoldPrelayoutGeometry
scaffoldGeometry
,
double
adjustment
)
{
if
(
scaffoldGeometry
.
contentTop
>
scaffoldGeometry
.
minViewPadding
.
top
)
{
final
double
fabHalfHeight
=
scaffoldGeometry
.
floatingActionButtonSize
.
height
/
2.0
;
final
double
fabHalfHeight
=
scaffoldGeometry
.
floatingActionButtonSize
.
height
/
2.0
;
return
scaffoldGeometry
.
contentTop
-
fabHalfHeight
;
return
scaffoldGeometry
.
contentTop
-
fabHalfHeight
;
}
}
// Otherwise, ensure we are placed within the bounds of a safe area.
return
scaffoldGeometry
.
minViewPadding
.
top
;
}
}
}
/// Mixin for a "float" floating action button location, such as [FloatingActionButtonLocation.centerFloat].
/// Mixin for a "float" floating action button location, such as [FloatingActionButtonLocation.centerFloat].
...
@@ -434,8 +446,12 @@ mixin FabFloatOffsetY on StandardFabLocation {
...
@@ -434,8 +446,12 @@ mixin FabFloatOffsetY on StandardFabLocation {
final
double
bottomSheetHeight
=
scaffoldGeometry
.
bottomSheetSize
.
height
;
final
double
bottomSheetHeight
=
scaffoldGeometry
.
bottomSheetSize
.
height
;
final
double
fabHeight
=
scaffoldGeometry
.
floatingActionButtonSize
.
height
;
final
double
fabHeight
=
scaffoldGeometry
.
floatingActionButtonSize
.
height
;
final
double
snackBarHeight
=
scaffoldGeometry
.
snackBarSize
.
height
;
final
double
snackBarHeight
=
scaffoldGeometry
.
snackBarSize
.
height
;
final
double
safeMargin
=
math
.
max
(
kFloatingActionButtonMargin
,
scaffoldGeometry
.
minViewPadding
.
bottom
,
);
double
fabY
=
contentBottom
-
fabHeight
-
kFloatingActionButton
Margin
;
double
fabY
=
contentBottom
-
fabHeight
-
safe
Margin
;
if
(
snackBarHeight
>
0.0
)
if
(
snackBarHeight
>
0.0
)
fabY
=
math
.
min
(
fabY
,
contentBottom
-
snackBarHeight
-
fabHeight
-
kFloatingActionButtonMargin
);
fabY
=
math
.
min
(
fabY
,
contentBottom
-
snackBarHeight
-
fabHeight
-
kFloatingActionButtonMargin
);
if
(
bottomSheetHeight
>
0.0
)
if
(
bottomSheetHeight
>
0.0
)
...
@@ -453,19 +469,21 @@ mixin FabDockedOffsetY on StandardFabLocation {
...
@@ -453,19 +469,21 @@ mixin FabDockedOffsetY on StandardFabLocation {
@override
@override
double
getOffsetY
(
ScaffoldPrelayoutGeometry
scaffoldGeometry
,
double
adjustment
)
{
double
getOffsetY
(
ScaffoldPrelayoutGeometry
scaffoldGeometry
,
double
adjustment
)
{
final
double
contentBottom
=
scaffoldGeometry
.
contentBottom
;
final
double
contentBottom
=
scaffoldGeometry
.
contentBottom
;
final
double
contentMargin
=
scaffoldGeometry
.
scaffoldSize
.
height
-
contentBottom
;
final
double
bottomViewPadding
=
scaffoldGeometry
.
minViewPadding
.
bottom
;
final
double
bottomSheetHeight
=
scaffoldGeometry
.
bottomSheetSize
.
height
;
final
double
bottomSheetHeight
=
scaffoldGeometry
.
bottomSheetSize
.
height
;
final
double
fabHeight
=
scaffoldGeometry
.
floatingActionButtonSize
.
height
;
final
double
fabHeight
=
scaffoldGeometry
.
floatingActionButtonSize
.
height
;
final
double
snackBarHeight
=
scaffoldGeometry
.
snackBarSize
.
height
;
final
double
snackBarHeight
=
scaffoldGeometry
.
snackBarSize
.
height
;
final
double
safeMargin
=
bottomViewPadding
>
contentMargin
?
bottomViewPadding
:
0.0
;
double
fabY
=
contentBottom
-
fabHeight
/
2.0
;
double
fabY
=
contentBottom
-
fabHeight
/
2.0
-
safeMargin
;
// The FAB should sit with a margin between it and the snack bar.
// The FAB should sit with a margin between it and the snack bar.
if
(
snackBarHeight
>
0.0
)
if
(
snackBarHeight
>
0.0
)
fabY
=
math
.
min
(
fabY
,
contentBottom
-
snackBarHeight
-
fabHeight
-
kFloatingActionButtonMargin
);
fabY
=
math
.
min
(
fabY
,
contentBottom
-
snackBarHeight
-
fabHeight
-
kFloatingActionButtonMargin
);
// The FAB should sit with its center in front of the top of the bottom sheet.
// The FAB should sit with its center in front of the top of the bottom sheet.
if
(
bottomSheetHeight
>
0.0
)
if
(
bottomSheetHeight
>
0.0
)
fabY
=
math
.
min
(
fabY
,
contentBottom
-
bottomSheetHeight
-
fabHeight
/
2.0
);
fabY
=
math
.
min
(
fabY
,
contentBottom
-
bottomSheetHeight
-
fabHeight
/
2.0
);
final
double
maxFabY
=
scaffoldGeometry
.
scaffoldSize
.
height
-
fabHeight
-
safeMargin
;
final
double
maxFabY
=
scaffoldGeometry
.
scaffoldSize
.
height
-
fabHeight
;
return
math
.
min
(
maxFabY
,
fabY
);
return
math
.
min
(
maxFabY
,
fabY
);
}
}
}
}
...
...
packages/flutter/lib/src/material/scaffold.dart
View file @
fd7a72ee
...
@@ -80,6 +80,7 @@ class ScaffoldPrelayoutGeometry {
...
@@ -80,6 +80,7 @@ class ScaffoldPrelayoutGeometry {
@required
this
.
contentTop
,
@required
this
.
contentTop
,
@required
this
.
floatingActionButtonSize
,
@required
this
.
floatingActionButtonSize
,
@required
this
.
minInsets
,
@required
this
.
minInsets
,
@required
this
.
minViewPadding
,
@required
this
.
scaffoldSize
,
@required
this
.
scaffoldSize
,
@required
this
.
snackBarSize
,
@required
this
.
snackBarSize
,
@required
this
.
textDirection
,
@required
this
.
textDirection
,
...
@@ -134,6 +135,16 @@ class ScaffoldPrelayoutGeometry {
...
@@ -134,6 +135,16 @@ class ScaffoldPrelayoutGeometry {
/// will be 0.0.
/// will be 0.0.
final
EdgeInsets
minInsets
;
final
EdgeInsets
minInsets
;
/// The minimum padding to inset interactive elements to be within a safe,
/// un-obscured space.
///
/// This value reflects the [MediaQuery.viewPadding] of the [Scaffold]'s
/// [BuildContext] when [Scaffold.resizeToAvoidBottomInset] is false or and
/// the [MediaQuery.viewInsets] > 0.0. This helps distinguish between
/// different types of obstructions on the screen, such as software keyboards
/// and physical device notches.
final
EdgeInsets
minViewPadding
;
/// The [Size] of the whole [Scaffold].
/// The [Size] of the whole [Scaffold].
///
///
/// If the [Size] of the [Scaffold]'s contents is modified by values such as
/// If the [Size] of the [Scaffold]'s contents is modified by values such as
...
@@ -389,6 +400,7 @@ class _BodyBuilder extends StatelessWidget {
...
@@ -389,6 +400,7 @@ class _BodyBuilder extends StatelessWidget {
class
_ScaffoldLayout
extends
MultiChildLayoutDelegate
{
class
_ScaffoldLayout
extends
MultiChildLayoutDelegate
{
_ScaffoldLayout
({
_ScaffoldLayout
({
@required
this
.
minInsets
,
@required
this
.
minInsets
,
@required
this
.
minViewPadding
,
@required
this
.
textDirection
,
@required
this
.
textDirection
,
@required
this
.
geometryNotifier
,
@required
this
.
geometryNotifier
,
// for floating action button
// for floating action button
...
@@ -410,6 +422,7 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
...
@@ -410,6 +422,7 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
final
bool
extendBody
;
final
bool
extendBody
;
final
bool
extendBodyBehindAppBar
;
final
bool
extendBodyBehindAppBar
;
final
EdgeInsets
minInsets
;
final
EdgeInsets
minInsets
;
final
EdgeInsets
minViewPadding
;
final
TextDirection
textDirection
;
final
TextDirection
textDirection
;
final
_ScaffoldGeometryNotifier
geometryNotifier
;
final
_ScaffoldGeometryNotifier
geometryNotifier
;
...
@@ -536,6 +549,7 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
...
@@ -536,6 +549,7 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
scaffoldSize:
size
,
scaffoldSize:
size
,
snackBarSize:
snackBarSize
,
snackBarSize:
snackBarSize
,
textDirection:
textDirection
,
textDirection:
textDirection
,
minViewPadding:
minViewPadding
,
);
);
final
Offset
currentFabOffset
=
currentFloatingActionButtonLocation
.
getOffset
(
currentGeometry
);
final
Offset
currentFabOffset
=
currentFloatingActionButtonLocation
.
getOffset
(
currentGeometry
);
final
Offset
previousFabOffset
=
previousFloatingActionButtonLocation
.
getOffset
(
currentGeometry
);
final
Offset
previousFabOffset
=
previousFloatingActionButtonLocation
.
getOffset
(
currentGeometry
);
...
@@ -2497,6 +2511,12 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin {
...
@@ -2497,6 +2511,12 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin {
bottom:
_resizeToAvoidBottomInset
?
mediaQuery
.
viewInsets
.
bottom
:
0.0
,
bottom:
_resizeToAvoidBottomInset
?
mediaQuery
.
viewInsets
.
bottom
:
0.0
,
);
);
// The minimum viewPadding for interactive elements positioned by the
// Scaffold to keep within safe interactive areas.
final
EdgeInsets
minViewPadding
=
mediaQuery
.
viewPadding
.
copyWith
(
bottom:
_resizeToAvoidBottomInset
&&
mediaQuery
.
viewInsets
.
bottom
!=
0.0
?
0.0
:
null
,
);
// extendBody locked when keyboard is open
// extendBody locked when keyboard is open
final
bool
_extendBody
=
minInsets
.
bottom
<=
0
&&
widget
.
extendBody
;
final
bool
_extendBody
=
minInsets
.
bottom
<=
0
&&
widget
.
extendBody
;
...
@@ -2514,6 +2534,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin {
...
@@ -2514,6 +2534,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin {
extendBody:
_extendBody
,
extendBody:
_extendBody
,
extendBodyBehindAppBar:
widget
.
extendBodyBehindAppBar
,
extendBodyBehindAppBar:
widget
.
extendBodyBehindAppBar
,
minInsets:
minInsets
,
minInsets:
minInsets
,
minViewPadding:
minViewPadding
,
currentFloatingActionButtonLocation:
_floatingActionButtonLocation
,
currentFloatingActionButtonLocation:
_floatingActionButtonLocation
,
floatingActionButtonMoveAnimationProgress:
_floatingActionButtonMoveController
.
value
,
floatingActionButtonMoveAnimationProgress:
_floatingActionButtonMoveController
.
value
,
floatingActionButtonMotionAnimator:
_floatingActionButtonAnimator
,
floatingActionButtonMotionAnimator:
_floatingActionButtonAnimator
,
...
...
packages/flutter/test/material/floating_action_button_location_test.dart
View file @
fd7a72ee
This diff is collapsed.
Click to expand it.
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