Custom offset functionality for Popup Menu Button (#22534)
* Adds offset functionality to popup menu * Adds a test
This commit is contained in:
parent
aa6a27e8a2
commit
f44b277fa6
@ -820,7 +820,9 @@ class PopupMenuButton<T> extends StatefulWidget {
|
||||
this.padding = const EdgeInsets.all(8.0),
|
||||
this.child,
|
||||
this.icon,
|
||||
this.offset = Offset.zero,
|
||||
}) : assert(itemBuilder != null),
|
||||
assert(offset != null),
|
||||
assert(!(child != null && icon != null)), // fails if passed both parameters
|
||||
super(key: key);
|
||||
|
||||
@ -864,6 +866,12 @@ class PopupMenuButton<T> extends StatefulWidget {
|
||||
/// If provided, the icon used for this button.
|
||||
final Icon icon;
|
||||
|
||||
/// The offset applied to the Popup Menu Button.
|
||||
///
|
||||
/// When not set, the Popup Menu Button will be positioned directly next to
|
||||
/// the button that was used to create it.
|
||||
final Offset offset;
|
||||
|
||||
@override
|
||||
_PopupMenuButtonState<T> createState() => _PopupMenuButtonState<T>();
|
||||
}
|
||||
@ -874,7 +882,7 @@ class _PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
|
||||
final RenderBox overlay = Overlay.of(context).context.findRenderObject();
|
||||
final RelativeRect position = RelativeRect.fromRect(
|
||||
Rect.fromPoints(
|
||||
button.localToGlobal(Offset.zero, ancestor: overlay),
|
||||
button.localToGlobal(widget.offset, ancestor: overlay),
|
||||
button.localToGlobal(button.size.bottomRight(Offset.zero), ancestor: overlay),
|
||||
),
|
||||
Offset.zero & overlay.size,
|
||||
|
@ -430,6 +430,45 @@ void main() {
|
||||
expect(MediaQuery.of(popupContext).padding, EdgeInsets.zero);
|
||||
});
|
||||
|
||||
testWidgets('Popup Menu Offset Test', (WidgetTester tester) async {
|
||||
const Offset offset = Offset(100.0, 100.0);
|
||||
|
||||
final PopupMenuButton<int> popupMenuButton =
|
||||
PopupMenuButton<int>(
|
||||
offset: offset,
|
||||
itemBuilder: (BuildContext context) {
|
||||
return <PopupMenuItem<int>>[
|
||||
PopupMenuItem<int>(
|
||||
value: 1,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return const Text('AAA');
|
||||
},
|
||||
),
|
||||
),
|
||||
];
|
||||
},
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Center(
|
||||
child: Material(
|
||||
child: popupMenuButton,
|
||||
),
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byType(IconButton));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The position is different than the offset because the default position isn't at the origin.
|
||||
expect(tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_PopupMenu<int>')), const Offset(364.0, 324.0));
|
||||
});
|
||||
|
||||
testWidgets('open PopupMenu has correct semantics', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
|
Loading…
x
Reference in New Issue
Block a user