Re-add the removed MediaQuery.removePadding of PopupMenuButton (#82986)
This commit is contained in:
parent
669a8150e0
commit
43d22ae2d3
@ -624,8 +624,7 @@ class _PopupMenuRouteLayout extends SingleChildLayoutDelegate {
|
||||
this.itemSizes,
|
||||
this.selectedItemIndex,
|
||||
this.textDirection,
|
||||
this.topPadding,
|
||||
this.bottomPadding,
|
||||
this.padding,
|
||||
);
|
||||
|
||||
// Rectangle of underlying button, relative to the overlay's dimensions.
|
||||
@ -642,11 +641,8 @@ class _PopupMenuRouteLayout extends SingleChildLayoutDelegate {
|
||||
// Whether to prefer going to the left or to the right.
|
||||
final TextDirection textDirection;
|
||||
|
||||
// Top padding of unsafe area.
|
||||
final double topPadding;
|
||||
|
||||
// Bottom padding of unsafe area.
|
||||
final double bottomPadding;
|
||||
// The padding of unsafe area.
|
||||
EdgeInsets padding;
|
||||
|
||||
// We put the child wherever position specifies, so long as it will fit within
|
||||
// the specified parent size padded (inset) by 8. If necessary, we adjust the
|
||||
@ -657,7 +653,7 @@ class _PopupMenuRouteLayout extends SingleChildLayoutDelegate {
|
||||
// The menu can be at most the size of the overlay minus 8.0 pixels in each
|
||||
// direction.
|
||||
return BoxConstraints.loose(constraints.biggest).deflate(
|
||||
const EdgeInsets.all(_kMenuScreenPadding) + EdgeInsets.only(top: topPadding, bottom: bottomPadding),
|
||||
const EdgeInsets.all(_kMenuScreenPadding) + padding,
|
||||
);
|
||||
}
|
||||
|
||||
@ -701,14 +697,15 @@ class _PopupMenuRouteLayout extends SingleChildLayoutDelegate {
|
||||
|
||||
// Avoid going outside an area defined as the rectangle 8.0 pixels from the
|
||||
// edge of the screen in every direction.
|
||||
if (x < _kMenuScreenPadding)
|
||||
x = _kMenuScreenPadding;
|
||||
else if (x + childSize.width > size.width - _kMenuScreenPadding)
|
||||
x = size.width - childSize.width - _kMenuScreenPadding;
|
||||
if (y < _kMenuScreenPadding + topPadding)
|
||||
y = _kMenuScreenPadding + topPadding;
|
||||
else if (y + childSize.height > size.height - _kMenuScreenPadding - bottomPadding)
|
||||
y = size.height - bottomPadding - _kMenuScreenPadding - childSize.height ;
|
||||
if (x < _kMenuScreenPadding + padding.left)
|
||||
x = _kMenuScreenPadding + padding.left;
|
||||
else if (x + childSize.width > size.width - _kMenuScreenPadding - padding.right)
|
||||
x = size.width - childSize.width - _kMenuScreenPadding - padding.right ;
|
||||
if (y < _kMenuScreenPadding + padding.top)
|
||||
y = _kMenuScreenPadding + padding.top;
|
||||
else if (y + childSize.height > size.height - _kMenuScreenPadding - padding.bottom)
|
||||
y = size.height - padding.bottom - _kMenuScreenPadding - childSize.height ;
|
||||
|
||||
return Offset(x, y);
|
||||
}
|
||||
|
||||
@ -723,8 +720,7 @@ class _PopupMenuRouteLayout extends SingleChildLayoutDelegate {
|
||||
|| selectedItemIndex != oldDelegate.selectedItemIndex
|
||||
|| textDirection != oldDelegate.textDirection
|
||||
|| !listEquals(itemSizes, oldDelegate.itemSizes)
|
||||
|| topPadding != oldDelegate.topPadding
|
||||
|| bottomPadding != oldDelegate.bottomPadding;
|
||||
|| padding != oldDelegate.padding;
|
||||
}
|
||||
}
|
||||
|
||||
@ -784,22 +780,27 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
|
||||
}
|
||||
|
||||
final Widget menu = _PopupMenu<T>(route: this, semanticLabel: semanticLabel);
|
||||
|
||||
return Builder(
|
||||
builder: (BuildContext context) {
|
||||
final MediaQueryData mediaQuery = MediaQuery.of(context);
|
||||
return MediaQuery.removePadding(
|
||||
context: context,
|
||||
removeTop: true,
|
||||
removeBottom: true,
|
||||
removeLeft: true,
|
||||
removeRight: true,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return CustomSingleChildLayout(
|
||||
delegate: _PopupMenuRouteLayout(
|
||||
position,
|
||||
itemSizes,
|
||||
selectedItemIndex,
|
||||
Directionality.of(context),
|
||||
mediaQuery.padding.top,
|
||||
mediaQuery.padding.bottom,
|
||||
mediaQuery.padding,
|
||||
),
|
||||
child: capturedThemes.wrap(menu),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2191,6 +2191,79 @@ void main() {
|
||||
expect(popupMenu, Offset(button.dx - 8.0, button.dy + 8.0));
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/82874
|
||||
testWidgets('PopupMenu position test when have unsafe area - left/right padding', (WidgetTester tester) async {
|
||||
final GlobalKey buttonKey = GlobalKey();
|
||||
const EdgeInsets padding = EdgeInsets.only(left: 300.0, top: 32.0, right: 310.0, bottom: 64.0);
|
||||
EdgeInsets? mediaQueryPadding;
|
||||
|
||||
Widget buildFrame(double width, double height) {
|
||||
return MaterialApp(
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
return MediaQuery(
|
||||
data: const MediaQueryData(
|
||||
padding: padding,
|
||||
),
|
||||
child: child!,
|
||||
);
|
||||
},
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('PopupMenu Test'),
|
||||
actions: <Widget>[PopupMenuButton<int>(
|
||||
child: SizedBox(
|
||||
key: buttonKey,
|
||||
height: height,
|
||||
width: width,
|
||||
child: const ColoredBox(
|
||||
color: Colors.pink,
|
||||
),
|
||||
),
|
||||
itemBuilder: (BuildContext context) {
|
||||
return <PopupMenuEntry<int>>[
|
||||
PopupMenuItem<int>(
|
||||
value: 1,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
mediaQueryPadding = MediaQuery.of(context).padding;
|
||||
return Text('-1-' * 500); // A long long text string.
|
||||
},
|
||||
),
|
||||
),
|
||||
const PopupMenuItem<int>(value: 2, child: Text('-2-')),
|
||||
];
|
||||
},
|
||||
)],
|
||||
),
|
||||
body: const SizedBox.shrink(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildFrame(20.0, 20.0));
|
||||
|
||||
await tester.tap(find.byKey(buttonKey));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final Offset button = tester.getTopRight(find.byKey(buttonKey));
|
||||
expect(button, Offset(800.0 - padding.right, padding.top)); // The topPadding is 32.0.
|
||||
|
||||
final Offset popupMenuTopRight = tester.getTopRight(find.byType(SingleChildScrollView));
|
||||
|
||||
// The menu should be positioned directly next to the top of the button.
|
||||
// The 8.0 pixels is [_kMenuScreenPadding].
|
||||
expect(popupMenuTopRight, Offset(800.0 - padding.right - 8.0, padding.top + 8.0));
|
||||
|
||||
final Offset popupMenuTopLeft = tester.getTopLeft(find.byType(SingleChildScrollView));
|
||||
expect(popupMenuTopLeft, Offset(padding.left + 8.0, padding.top + 8.0));
|
||||
|
||||
final Offset popupMenuBottomLeft = tester.getBottomLeft(find.byType(SingleChildScrollView));
|
||||
expect(popupMenuBottomLeft, Offset(padding.left + 8.0, 600.0 - padding.bottom - 8.0));
|
||||
|
||||
// The `MediaQueryData.padding` should be removed.
|
||||
expect(mediaQueryPadding, EdgeInsets.zero);
|
||||
});
|
||||
|
||||
group('feedback', () {
|
||||
late FeedbackTester feedback;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user