Fix DropdownButton crash when viewport size is too small for the entirety of the menu's height (#76764)
This commit is contained in:
parent
fc77610dd6
commit
8d866d9c02
@ -65,12 +65,12 @@ class _DropdownMenuPainter extends CustomPainter {
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final double selectedItemOffset = getSelectedItemOffset();
|
||||
final Tween<double> top = Tween<double>(
|
||||
begin: selectedItemOffset.clamp(0.0, size.height - _kMenuItemHeight),
|
||||
begin: selectedItemOffset.clamp(0.0, math.max(size.height - _kMenuItemHeight, 0.0)),
|
||||
end: 0.0,
|
||||
);
|
||||
|
||||
final Tween<double> bottom = Tween<double>(
|
||||
begin: (top.begin! + _kMenuItemHeight).clamp(_kMenuItemHeight, size.height),
|
||||
begin: (top.begin! + _kMenuItemHeight).clamp(math.min(_kMenuItemHeight, size.height), size.height),
|
||||
end: size.height,
|
||||
);
|
||||
|
||||
|
@ -3008,4 +3008,61 @@ void main() {
|
||||
expect(scrollController.position.maxScrollExtent > 0, isTrue);
|
||||
expect(find.byType(Scrollbar), paints..rect());
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/76614
|
||||
testWidgets('Do not crash if used in very short screen', (WidgetTester tester) async {
|
||||
// The default item height is 48.0 pixels and needs two items padding since
|
||||
// the menu requires empty space surrounding the menu. Finally, the constraint height
|
||||
// is 47.0 pixels for the menu rendering.
|
||||
tester.binding.window.physicalSizeTestValue = const Size(800.0, 48.0 * 3 - 1.0);
|
||||
tester.binding.window.devicePixelRatioTestValue = 1;
|
||||
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
||||
addTearDown(tester.binding.window.clearDevicePixelRatioTestValue);
|
||||
|
||||
const String value = 'foo';
|
||||
final UniqueKey itemKey = UniqueKey();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Center(
|
||||
child: DropdownButton<String>(
|
||||
value: value,
|
||||
items: <DropdownMenuItem<String>>[
|
||||
DropdownMenuItem<String>(
|
||||
key: itemKey,
|
||||
value: value,
|
||||
child: const Text(value),
|
||||
),
|
||||
],
|
||||
onChanged: (_) { },
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text(value));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final List<RenderBox> itemBoxes = tester.renderObjectList<RenderBox>(find.byKey(itemKey)).toList();
|
||||
expect(itemBoxes[0].localToGlobal(Offset.zero).dx, 364.0);
|
||||
expect(itemBoxes[0].localToGlobal(Offset.zero).dy, 47.5);
|
||||
|
||||
expect(itemBoxes[1].localToGlobal(Offset.zero).dx, 364.0);
|
||||
expect(itemBoxes[1].localToGlobal(Offset.zero).dy, 47.5);
|
||||
|
||||
expect(
|
||||
find.ancestor(
|
||||
of: find.text(value).last,
|
||||
matching: find.byType(CustomPaint),
|
||||
).at(2),
|
||||
paints
|
||||
..save()
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect()
|
||||
// The height of menu is 47.0.
|
||||
..rrect(rrect: const RRect.fromLTRBXY(0.0, 0.0, 112.0, 47.0, 2.0, 2.0), color: Colors.grey[50], hasMaskFilter: false)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user