Unverified Commit 89acdb03 authored by chunhtai's avatar chunhtai Committed by GitHub

fix dropdown menu to position based on nearest navigator (#73381)

parent 7a0e3a30
......@@ -1188,8 +1188,6 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
TextStyle? get _textStyle => widget.style ?? Theme.of(context).textTheme.subtitle1;
void _handleTap() {
final RenderBox itemBox = context.findRenderObject()! as RenderBox;
final Rect itemRect = itemBox.localToGlobal(Offset.zero) & itemBox.size;
final TextDirection? textDirection = Directionality.maybeOf(context);
final EdgeInsetsGeometry menuMargin = ButtonTheme.of(context).alignedDropdown
? _kAlignedMenuMargin
......@@ -1218,6 +1216,8 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
final NavigatorState navigator = Navigator.of(context);
assert(_dropdownRoute == null);
final RenderBox itemBox = context.findRenderObject()! as RenderBox;
final Rect itemRect = itemBox.localToGlobal(Offset.zero, ancestor: navigator.context.findRenderObject()) & itemBox.size;
_dropdownRoute = _DropdownRoute<T>(
items: menuItems,
buttonRect: menuMargin.resolve(textDirection).inflateRect(itemRect),
......
......@@ -586,6 +586,51 @@ void main() {
expect(itemBoxes[1].size.width, equals(800.0 - 16.0 * 2));
});
testWidgets('Dropdown menu can position correctly inside a nested navigator', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/66870
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Column(
children: <Widget>[
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 500, maxHeight: 200),
child: Navigator(
onGenerateRoute: (RouteSettings s) {
return MaterialPageRoute<void>(builder: (BuildContext context) {
return Center(
child: DropdownButton<int>(
value: 1,
items: const <DropdownMenuItem<int>>[
DropdownMenuItem<int>(
child: Text('First Item'),
value: 1,
),
DropdownMenuItem<int>(
child: Text('Second Item'),
value: 2,
),
],
onChanged: (_) { },
),
);
});
},
),
),
],
),
),
),
);
await tester.tap(find.text('First Item'));
await tester.pump();
final RenderBox secondItem = tester.renderObjectList<RenderBox>(find.text('Second Item')).toList()[1];
expect(secondItem.localToGlobal(Offset.zero).dx, equals(150.0));
expect(secondItem.localToGlobal(Offset.zero).dy, equals(176.0));
});
testWidgets('Dropdown screen edges', (WidgetTester tester) async {
int? value = 4;
final List<DropdownMenuItem<int>> items = <DropdownMenuItem<int>>[
......
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