Fix DatePickerDialog
& DateRangePickerDialog
overflow when resized from landscape to portrait (#133327)
fixes [resize window with a `showDateRangePicker` will make RenderFlex overflowed error](https://github.com/flutter/flutter/issues/131989) ### Description - This fixes `DatePickerDialog` & `DateRangePickerDialog` overflow error when resized from landscape to portrait. - Added tests that check these two widgets from landscape to portrait for no overflow errors. <details <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( debugShowCheckedModeBanner: false, home: Example(), ); } } class Example extends StatefulWidget { const Example({super.key}); @override State<Example> createState() => _ExampleState(); } class _ExampleState extends State<Example> { bool _portait = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('DatePicker & DateRangePicker'), ), body: MediaQuery( data: MediaQuery.of(context).copyWith( size: _portait ? const Size(400, 800) : const Size(800, 400), ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ DatePickerDialog( initialDate: DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime(2030), initialEntryMode: DatePickerEntryMode.inputOnly, ), DateRangePickerDialog( currentDate: DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime(2030), initialEntryMode: DatePickerEntryMode.inputOnly, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { _portait = !_portait; }); }, child: const Icon(Icons.refresh), ), ); } } ``` </details> ### Before https://github.com/flutter/flutter/assets/48603081/81387cbb-cdcf-42bd-b4f8-b7a08317c955 ### After https://github.com/flutter/flutter/assets/48603081/36d28ea9-cfed-48ad-90f5-0459755e08c0
This commit is contained in:
parent
e7fc5a6e51
commit
a0943e6533
@ -674,7 +674,12 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
|
||||
// Constrain the textScaleFactor to the largest supported value to prevent
|
||||
// layout issues.
|
||||
maxScaleFactor: _kMaxTextScaleFactor,
|
||||
child: Builder(builder: (BuildContext context) {
|
||||
child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
|
||||
final Size portraitDialogSize = useMaterial3 ? _inputPortraitDialogSizeM3 : _inputPortraitDialogSizeM2;
|
||||
// Make sure the portrait dialog can fit the contents comfortably when
|
||||
// resized from the landscape dialog.
|
||||
final bool isFullyPortrait = constraints.maxHeight >= portraitDialogSize.height;
|
||||
|
||||
switch (orientation) {
|
||||
case Orientation.portrait:
|
||||
return Column(
|
||||
@ -683,8 +688,10 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
|
||||
children: <Widget>[
|
||||
header,
|
||||
if (useMaterial3) Divider(height: 0, color: datePickerTheme.dividerColor),
|
||||
Expanded(child: picker),
|
||||
actions,
|
||||
if (isFullyPortrait) ...<Widget>[
|
||||
Expanded(child: picker),
|
||||
actions,
|
||||
],
|
||||
],
|
||||
);
|
||||
case Orientation.landscape:
|
||||
@ -2775,14 +2782,25 @@ class _InputDateRangePickerDialog extends StatelessWidget {
|
||||
|
||||
switch (orientation) {
|
||||
case Orientation.portrait:
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
header,
|
||||
Expanded(child: picker),
|
||||
actions,
|
||||
],
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
final Size portraitDialogSize = useMaterial3 ? _inputPortraitDialogSizeM3 : _inputPortraitDialogSizeM2;
|
||||
// Make sure the portrait dialog can fit the contents comfortably when
|
||||
// resized from the landscape dialog.
|
||||
final bool isFullyPortrait = constraints.maxHeight >= portraitDialogSize.height;
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
header,
|
||||
if (isFullyPortrait) ...<Widget>[
|
||||
Expanded(child: picker),
|
||||
actions,
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
case Orientation.landscape:
|
||||
|
@ -1469,6 +1469,22 @@ void main() {
|
||||
expect(tester.takeException(), null);
|
||||
});
|
||||
});
|
||||
|
||||
// This is a regression test for https://github.com/flutter/flutter/issues/131989.
|
||||
testWidgets('Dialog contents do not overflow when resized from landscape to portrait',
|
||||
(WidgetTester tester) async {
|
||||
addTearDown(tester.view.reset);
|
||||
// Initial window size is wide for landscape mode.
|
||||
tester.view.physicalSize = wideWindowSize;
|
||||
tester.view.devicePixelRatio = 1.0;
|
||||
|
||||
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||
// Change window size to narrow for portrait mode.
|
||||
tester.view.physicalSize = narrowWindowSize;
|
||||
await tester.pump();
|
||||
expect(tester.takeException(), null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('Semantics', () {
|
||||
|
@ -53,6 +53,9 @@ void main() {
|
||||
saveText = null;
|
||||
});
|
||||
|
||||
const Size wideWindowSize = Size(1920.0, 1080.0);
|
||||
const Size narrowWindowSize = Size(1070.0, 1770.0);
|
||||
|
||||
Future<void> preparePicker(
|
||||
WidgetTester tester,
|
||||
Future<void> Function(Future<DateTimeRange?> date) callback, {
|
||||
@ -1065,6 +1068,22 @@ void main() {
|
||||
// Test the end date text field
|
||||
testInputDecorator(tester.widget(borderContainers.last), border, Colors.transparent);
|
||||
});
|
||||
|
||||
// This is a regression test for https://github.com/flutter/flutter/issues/131989.
|
||||
testWidgets('Dialog contents do not overflow when resized from landscape to portrait',
|
||||
(WidgetTester tester) async {
|
||||
addTearDown(tester.view.reset);
|
||||
// Initial window size is wide for landscape mode.
|
||||
tester.view.physicalSize = wideWindowSize;
|
||||
tester.view.devicePixelRatio = 1.0;
|
||||
|
||||
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||
// Change window size to narrow for portrait mode.
|
||||
tester.view.physicalSize = narrowWindowSize;
|
||||
await tester.pump();
|
||||
expect(tester.takeException(), null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('DatePickerDialog is state restorable', (WidgetTester tester) async {
|
||||
|
Loading…
x
Reference in New Issue
Block a user