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
|
// Constrain the textScaleFactor to the largest supported value to prevent
|
||||||
// layout issues.
|
// layout issues.
|
||||||
maxScaleFactor: _kMaxTextScaleFactor,
|
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) {
|
switch (orientation) {
|
||||||
case Orientation.portrait:
|
case Orientation.portrait:
|
||||||
return Column(
|
return Column(
|
||||||
@ -683,8 +688,10 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
header,
|
header,
|
||||||
if (useMaterial3) Divider(height: 0, color: datePickerTheme.dividerColor),
|
if (useMaterial3) Divider(height: 0, color: datePickerTheme.dividerColor),
|
||||||
Expanded(child: picker),
|
if (isFullyPortrait) ...<Widget>[
|
||||||
actions,
|
Expanded(child: picker),
|
||||||
|
actions,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
case Orientation.landscape:
|
case Orientation.landscape:
|
||||||
@ -2775,14 +2782,25 @@ class _InputDateRangePickerDialog extends StatelessWidget {
|
|||||||
|
|
||||||
switch (orientation) {
|
switch (orientation) {
|
||||||
case Orientation.portrait:
|
case Orientation.portrait:
|
||||||
return Column(
|
return LayoutBuilder(
|
||||||
mainAxisSize: MainAxisSize.min,
|
builder: (BuildContext context, BoxConstraints constraints) {
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
final Size portraitDialogSize = useMaterial3 ? _inputPortraitDialogSizeM3 : _inputPortraitDialogSizeM2;
|
||||||
children: <Widget>[
|
// Make sure the portrait dialog can fit the contents comfortably when
|
||||||
header,
|
// resized from the landscape dialog.
|
||||||
Expanded(child: picker),
|
final bool isFullyPortrait = constraints.maxHeight >= portraitDialogSize.height;
|
||||||
actions,
|
|
||||||
],
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: <Widget>[
|
||||||
|
header,
|
||||||
|
if (isFullyPortrait) ...<Widget>[
|
||||||
|
Expanded(child: picker),
|
||||||
|
actions,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
case Orientation.landscape:
|
case Orientation.landscape:
|
||||||
|
@ -1469,6 +1469,22 @@ void main() {
|
|||||||
expect(tester.takeException(), null);
|
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', () {
|
group('Semantics', () {
|
||||||
|
@ -53,6 +53,9 @@ void main() {
|
|||||||
saveText = null;
|
saveText = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const Size wideWindowSize = Size(1920.0, 1080.0);
|
||||||
|
const Size narrowWindowSize = Size(1070.0, 1770.0);
|
||||||
|
|
||||||
Future<void> preparePicker(
|
Future<void> preparePicker(
|
||||||
WidgetTester tester,
|
WidgetTester tester,
|
||||||
Future<void> Function(Future<DateTimeRange?> date) callback, {
|
Future<void> Function(Future<DateTimeRange?> date) callback, {
|
||||||
@ -1065,6 +1068,22 @@ void main() {
|
|||||||
// Test the end date text field
|
// Test the end date text field
|
||||||
testInputDecorator(tester.widget(borderContainers.last), border, Colors.transparent);
|
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 {
|
testWidgets('DatePickerDialog is state restorable', (WidgetTester tester) async {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user