Commit d62832b9 authored by Collin Jackson's avatar Collin Jackson Committed by GitHub

Fix dropdown buttons menus being clipped by the edge of the screen (#12059)

Fix dropdown buttons menus being clipped by the edge of the screen
parent e163a815
...@@ -203,7 +203,9 @@ class _DropdownMenuRouteLayout<T> extends SingleChildLayoutDelegate { ...@@ -203,7 +203,9 @@ class _DropdownMenuRouteLayout<T> extends SingleChildLayoutDelegate {
// with which to dismiss the menu. // with which to dismiss the menu.
// -- https://material.google.com/components/menus.html#menus-simple-menus // -- https://material.google.com/components/menus.html#menus-simple-menus
final double maxHeight = math.max(0.0, constraints.maxHeight - 2 * _kMenuItemHeight); final double maxHeight = math.max(0.0, constraints.maxHeight - 2 * _kMenuItemHeight);
final double width = buttonRect.width + 8.0; // The width of a menu should be at most the view width. This ensures that
// the menu does not extend past the left and right edges of the screen.
final double width = math.min(constraints.maxWidth, buttonRect.width + 8.0);
return new BoxConstraints( return new BoxConstraints(
minWidth: width, minWidth: width,
maxWidth: width, maxWidth: width,
...@@ -225,9 +227,7 @@ class _DropdownMenuRouteLayout<T> extends SingleChildLayoutDelegate { ...@@ -225,9 +227,7 @@ class _DropdownMenuRouteLayout<T> extends SingleChildLayoutDelegate {
} }
return true; return true;
}); });
return new Offset(buttonRect.left.clamp(0.0, size.width - childSize.width), menuTop);
final double width = buttonRect.width + 8.0;
return new Offset(buttonRect.left.clamp(0.0, size.width - width), menuTop);
} }
@override @override
......
...@@ -164,6 +164,41 @@ void main() { ...@@ -164,6 +164,41 @@ void main() {
expect(value, equals('two')); expect(value, equals('two'));
}); });
testWidgets('Dropdown in ListView', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/12053
// Positions a DropdownButton at the left and right edges of the screen,
// forcing it to be sized down to the viewport width
final String value = 'foo';
final UniqueKey itemKey = new UniqueKey();
await tester.pumpWidget(
new MaterialApp(
home: new Material(
child: new ListView(
children: <Widget>[
new DropdownButton<String>(
value: value,
items: <DropdownMenuItem<String>>[
new DropdownMenuItem<String>(
key: itemKey,
value: value,
child: new Text(value),
),
],
onChanged: (_) {},
),
],
),
),
),
);
await tester.tap(find.text(value));
await tester.pump();
final List<RenderBox> itemBoxes = tester.renderObjectList(find.byKey(itemKey)).toList();
expect(itemBoxes[0].localToGlobal(Offset.zero).dx, equals(0.0));
expect(itemBoxes[1].localToGlobal(Offset.zero).dx, equals(16.0));
expect(itemBoxes[1].size.width, equals(800.0 - 16.0 * 2));
});
testWidgets('Dropdown screen edges', (WidgetTester tester) async { testWidgets('Dropdown screen edges', (WidgetTester tester) async {
int value = 4; int value = 4;
final List<DropdownMenuItem<int>> items = <DropdownMenuItem<int>>[]; 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