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.itemSizes,
|
||||||
this.selectedItemIndex,
|
this.selectedItemIndex,
|
||||||
this.textDirection,
|
this.textDirection,
|
||||||
this.topPadding,
|
this.padding,
|
||||||
this.bottomPadding,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Rectangle of underlying button, relative to the overlay's dimensions.
|
// 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.
|
// Whether to prefer going to the left or to the right.
|
||||||
final TextDirection textDirection;
|
final TextDirection textDirection;
|
||||||
|
|
||||||
// Top padding of unsafe area.
|
// The padding of unsafe area.
|
||||||
final double topPadding;
|
EdgeInsets padding;
|
||||||
|
|
||||||
// Bottom padding of unsafe area.
|
|
||||||
final double bottomPadding;
|
|
||||||
|
|
||||||
// We put the child wherever position specifies, so long as it will fit within
|
// 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
|
// 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
|
// The menu can be at most the size of the overlay minus 8.0 pixels in each
|
||||||
// direction.
|
// direction.
|
||||||
return BoxConstraints.loose(constraints.biggest).deflate(
|
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
|
// Avoid going outside an area defined as the rectangle 8.0 pixels from the
|
||||||
// edge of the screen in every direction.
|
// edge of the screen in every direction.
|
||||||
if (x < _kMenuScreenPadding)
|
if (x < _kMenuScreenPadding + padding.left)
|
||||||
x = _kMenuScreenPadding;
|
x = _kMenuScreenPadding + padding.left;
|
||||||
else if (x + childSize.width > size.width - _kMenuScreenPadding)
|
else if (x + childSize.width > size.width - _kMenuScreenPadding - padding.right)
|
||||||
x = size.width - childSize.width - _kMenuScreenPadding;
|
x = size.width - childSize.width - _kMenuScreenPadding - padding.right ;
|
||||||
if (y < _kMenuScreenPadding + topPadding)
|
if (y < _kMenuScreenPadding + padding.top)
|
||||||
y = _kMenuScreenPadding + topPadding;
|
y = _kMenuScreenPadding + padding.top;
|
||||||
else if (y + childSize.height > size.height - _kMenuScreenPadding - bottomPadding)
|
else if (y + childSize.height > size.height - _kMenuScreenPadding - padding.bottom)
|
||||||
y = size.height - bottomPadding - _kMenuScreenPadding - childSize.height ;
|
y = size.height - padding.bottom - _kMenuScreenPadding - childSize.height ;
|
||||||
|
|
||||||
return Offset(x, y);
|
return Offset(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -723,8 +720,7 @@ class _PopupMenuRouteLayout extends SingleChildLayoutDelegate {
|
|||||||
|| selectedItemIndex != oldDelegate.selectedItemIndex
|
|| selectedItemIndex != oldDelegate.selectedItemIndex
|
||||||
|| textDirection != oldDelegate.textDirection
|
|| textDirection != oldDelegate.textDirection
|
||||||
|| !listEquals(itemSizes, oldDelegate.itemSizes)
|
|| !listEquals(itemSizes, oldDelegate.itemSizes)
|
||||||
|| topPadding != oldDelegate.topPadding
|
|| padding != oldDelegate.padding;
|
||||||
|| bottomPadding != oldDelegate.bottomPadding;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,22 +780,27 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Widget menu = _PopupMenu<T>(route: this, semanticLabel: semanticLabel);
|
final Widget menu = _PopupMenu<T>(route: this, semanticLabel: semanticLabel);
|
||||||
|
|
||||||
return Builder(
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
final MediaQueryData mediaQuery = MediaQuery.of(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(
|
return CustomSingleChildLayout(
|
||||||
delegate: _PopupMenuRouteLayout(
|
delegate: _PopupMenuRouteLayout(
|
||||||
position,
|
position,
|
||||||
itemSizes,
|
itemSizes,
|
||||||
selectedItemIndex,
|
selectedItemIndex,
|
||||||
Directionality.of(context),
|
Directionality.of(context),
|
||||||
mediaQuery.padding.top,
|
mediaQuery.padding,
|
||||||
mediaQuery.padding.bottom,
|
|
||||||
),
|
),
|
||||||
child: capturedThemes.wrap(menu),
|
child: capturedThemes.wrap(menu),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2191,6 +2191,79 @@ void main() {
|
|||||||
expect(popupMenu, Offset(button.dx - 8.0, button.dy + 8.0));
|
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', () {
|
group('feedback', () {
|
||||||
late FeedbackTester feedback;
|
late FeedbackTester feedback;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user