Unverified Commit 43d22ae2 authored by xubaolin's avatar xubaolin Committed by GitHub

Re-add the removed MediaQuery.removePadding of PopupMenuButton (#82986)

parent 669a8150
......@@ -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 CustomSingleChildLayout(
delegate: _PopupMenuRouteLayout(
position,
itemSizes,
selectedItemIndex,
Directionality.of(context),
mediaQuery.padding.top,
mediaQuery.padding.bottom,
),
child: capturedThemes.wrap(menu),
);
},
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,
),
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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment