[FloatingActionButtonLocation] Avoid docked FAB to be clipped by the software keyboard (#77769)
This commit is contained in:
parent
5a6bac3037
commit
2415eca4d2
@ -584,7 +584,23 @@ mixin FabDockedOffsetY 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 = bottomViewPadding > contentMargin ? bottomViewPadding : 0.0;
|
final double bottomMinInset = scaffoldGeometry.minInsets.bottom;
|
||||||
|
|
||||||
|
double safeMargin;
|
||||||
|
|
||||||
|
if (contentMargin > bottomMinInset + fabHeight / 2.0) {
|
||||||
|
// If contentMargin is higher than bottomMinInset enough to display the
|
||||||
|
// FAB without clipping, don't provide a margin
|
||||||
|
safeMargin = 0.0;
|
||||||
|
} else if (bottomMinInset == 0.0) {
|
||||||
|
// If bottomMinInset is zero(the software keyboard is not on the screen)
|
||||||
|
// provide bottomViewPadding as margin
|
||||||
|
safeMargin = bottomViewPadding;
|
||||||
|
} else {
|
||||||
|
// Provide a margin that would shift the FAB enough so that it stays away
|
||||||
|
// from the keyboard
|
||||||
|
safeMargin = fabHeight / 2.0 + kFloatingActionButtonMargin;
|
||||||
|
}
|
||||||
|
|
||||||
double fabY = contentBottom - fabHeight / 2.0 - safeMargin;
|
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.
|
||||||
|
@ -1037,7 +1037,9 @@ void main() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test docked locations, for each (6), keyboard presented or not:
|
// Test docked locations, for each (6), keyboard presented or not.
|
||||||
|
// If keyboard is presented and resizeToAvoidBottomInset: true, test whether
|
||||||
|
// the FAB is away from the keyboard(and thus not clipped):
|
||||||
// - Default
|
// - Default
|
||||||
// - Default with resizeToAvoidBottomInset: false
|
// - Default with resizeToAvoidBottomInset: false
|
||||||
// - docked with BottomNavigationBar
|
// - docked with BottomNavigationBar
|
||||||
@ -1057,6 +1059,7 @@ void main() {
|
|||||||
const double keyboardHeight = 200.0;
|
const double keyboardHeight = 200.0;
|
||||||
const double viewPadding = 50.0;
|
const double viewPadding = 50.0;
|
||||||
const double bottomNavHeight = 106.0;
|
const double bottomNavHeight = 106.0;
|
||||||
|
const double scaffoldHeight = 600.0;
|
||||||
final Key floatingActionButton = UniqueKey();
|
final Key floatingActionButton = UniqueKey();
|
||||||
final double fabHeight = mini ? 48.0 : 56.0;
|
final double fabHeight = mini ? 48.0 : 56.0;
|
||||||
// Default
|
// Default
|
||||||
@ -1084,9 +1087,14 @@ void main() {
|
|||||||
tester.getRect(find.byKey(floatingActionButton)),
|
tester.getRect(find.byKey(floatingActionButton)),
|
||||||
rectMoreOrLessEquals(defaultRect.translate(
|
rectMoreOrLessEquals(defaultRect.translate(
|
||||||
0.0,
|
0.0,
|
||||||
viewPadding - keyboardHeight + fabHeight / 2.0,
|
viewPadding - keyboardHeight - kFloatingActionButtonMargin,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
// The FAB should be away from the keyboard
|
||||||
|
expect(
|
||||||
|
tester.getRect(find.byKey(floatingActionButton)).bottom,
|
||||||
|
lessThan(scaffoldHeight - keyboardHeight),
|
||||||
|
);
|
||||||
|
|
||||||
// With resizeToAvoidBottomInset: false
|
// With resizeToAvoidBottomInset: false
|
||||||
// With keyboard presented, should maintain default position
|
// With keyboard presented, should maintain default position
|
||||||
@ -1136,9 +1144,14 @@ void main() {
|
|||||||
tester.getRect(find.byKey(floatingActionButton)),
|
tester.getRect(find.byKey(floatingActionButton)),
|
||||||
rectMoreOrLessEquals(bottomNavigationBarRect.translate(
|
rectMoreOrLessEquals(bottomNavigationBarRect.translate(
|
||||||
0.0,
|
0.0,
|
||||||
-keyboardHeight + bottomNavHeight,
|
bottomNavHeight + fabHeight / 2.0 - keyboardHeight - kFloatingActionButtonMargin - fabHeight,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
// The FAB should be away from the keyboard
|
||||||
|
expect(
|
||||||
|
tester.getRect(find.byKey(floatingActionButton)).bottom,
|
||||||
|
lessThan(scaffoldHeight - keyboardHeight),
|
||||||
|
);
|
||||||
|
|
||||||
// BottomNavigationBar with resizeToAvoidBottomInset: false
|
// BottomNavigationBar with resizeToAvoidBottomInset: false
|
||||||
// With keyboard presented, should maintain default position
|
// With keyboard presented, should maintain default position
|
||||||
@ -1195,6 +1208,11 @@ void main() {
|
|||||||
-keyboardHeight + bottomNavHeight,
|
-keyboardHeight + bottomNavHeight,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
// The FAB should be away from the keyboard
|
||||||
|
expect(
|
||||||
|
tester.getRect(find.byKey(floatingActionButton)).bottom,
|
||||||
|
lessThan(scaffoldHeight - keyboardHeight),
|
||||||
|
);
|
||||||
|
|
||||||
// BottomNavigationBar + BottomSheet with resizeToAvoidBottomInset: false
|
// BottomNavigationBar + BottomSheet with resizeToAvoidBottomInset: false
|
||||||
// With keyboard presented, should maintain default position
|
// With keyboard presented, should maintain default position
|
||||||
@ -1264,6 +1282,11 @@ void main() {
|
|||||||
tester.getRect(find.byKey(floatingActionButton)),
|
tester.getRect(find.byKey(floatingActionButton)),
|
||||||
rectMoreOrLessEquals(snackBarRect.translate(0.0, -keyboardHeight)),
|
rectMoreOrLessEquals(snackBarRect.translate(0.0, -keyboardHeight)),
|
||||||
);
|
);
|
||||||
|
// The FAB should be away from the keyboard
|
||||||
|
expect(
|
||||||
|
tester.getRect(find.byKey(floatingActionButton)).bottom,
|
||||||
|
lessThan(scaffoldHeight - keyboardHeight),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
testWidgets('startDocked', (WidgetTester tester) async {
|
testWidgets('startDocked', (WidgetTester tester) async {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user