Fix immediately overriding the user's chosen AM/PM selection (#26904)
This commit is contained in:
parent
6bb4b12633
commit
a872514ad8
@ -351,16 +351,35 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> {
|
||||
// in the widget after first build is ignored.
|
||||
DateTime initialDateTime;
|
||||
|
||||
// The currently selected values of the date picker.
|
||||
int selectedDayFromInitial; // The difference in days between the initial date and the currently selected date.
|
||||
// The difference in days between the initial date and the currently selected date.
|
||||
int selectedDayFromInitial;
|
||||
|
||||
// The current selection of the hour picker.
|
||||
//
|
||||
// If [widget.use24hFormat] is true, values range from 1-24. Otherwise values
|
||||
// range from 1-12.
|
||||
int selectedHour;
|
||||
|
||||
// The previous selection index of the hour column.
|
||||
//
|
||||
// This ranges from 0-23 even if [widget.use24hFormat] is false. As a result,
|
||||
// it can be used for determining if we just changed from AM -> PM or vice
|
||||
// versa.
|
||||
int previousHourIndex;
|
||||
|
||||
// The current selection of the minute picker. Values range from 0 to 59.
|
||||
int selectedMinute;
|
||||
int selectedAmPm; // 0 means AM, 1 means PM.
|
||||
|
||||
// The current selection of the AM/PM picker.
|
||||
//
|
||||
// - 0 means AM
|
||||
// - 1 means PM
|
||||
int selectedAmPm;
|
||||
|
||||
// The controller of the AM/PM column.
|
||||
FixedExtentScrollController amPmController;
|
||||
|
||||
// Estimated width of columns.
|
||||
// The estimated width of columns.
|
||||
final Map<int, double> estimatedColumnWidths = <int, double>{};
|
||||
|
||||
@override
|
||||
@ -380,6 +399,8 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> {
|
||||
|
||||
amPmController = FixedExtentScrollController(initialItem: selectedAmPm);
|
||||
}
|
||||
|
||||
previousHourIndex = selectedHour;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -477,25 +498,29 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> {
|
||||
if (widget.use24hFormat) {
|
||||
selectedHour = index;
|
||||
widget.onDateTimeChanged(_getDateTime());
|
||||
}
|
||||
else {
|
||||
final int currentHourIn24h = selectedHour + selectedAmPm * 12;
|
||||
} else {
|
||||
selectedHour = index % 12;
|
||||
|
||||
// Automatically scrolls the am/pm column when the hour column value
|
||||
// goes far enough. This behavior is similar to
|
||||
// iOS picker version.
|
||||
if (currentHourIn24h ~/ 12 != index ~/ 12) {
|
||||
selectedHour = index % 12;
|
||||
// goes far enough.
|
||||
|
||||
final bool wasAm = previousHourIndex >=0 && previousHourIndex <= 11;
|
||||
final bool isAm = index >= 0 && index <= 11;
|
||||
|
||||
if (wasAm != isAm) {
|
||||
// Animation values obtained by comparing with iOS version.
|
||||
amPmController.animateToItem(
|
||||
1 - amPmController.selectedItem,
|
||||
duration: const Duration(milliseconds: 300), // Set by comparing with iOS version.
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOut,
|
||||
); // Set by comparing with iOS version.
|
||||
);
|
||||
}
|
||||
else {
|
||||
selectedHour = index % 12;
|
||||
widget.onDateTimeChanged(_getDateTime());
|
||||
}
|
||||
}
|
||||
|
||||
previousHourIndex = index;
|
||||
},
|
||||
children: List<Widget>.generate(24, (int index) {
|
||||
int hour = index;
|
||||
|
@ -7,6 +7,9 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/semantics.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
// scrolling by this offset will move the picker to the next item
|
||||
const Offset _kRowOffset = Offset(0.0, -32.0);
|
||||
|
||||
void main() {
|
||||
group('Countdown timer picker', () {
|
||||
testWidgets('onTimerDurationChanged is not null', (WidgetTester tester) async {
|
||||
@ -524,6 +527,53 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('picker persists am/pm value when scrolling hours', (WidgetTester tester) async {
|
||||
DateTime date;
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: SizedBox(
|
||||
height: 400.0,
|
||||
width: 400.0,
|
||||
child: CupertinoDatePicker(
|
||||
mode: CupertinoDatePickerMode.time,
|
||||
onDateTimeChanged: (DateTime newDate) {
|
||||
date = newDate;
|
||||
},
|
||||
initialDateTime: DateTime(2019, 1, 1, 3),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// 3:00 -> 15:00
|
||||
await tester.drag(find.text('AM'), _kRowOffset);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(date, DateTime(2019, 1, 1, 15));
|
||||
|
||||
// 15:00 -> 16:00
|
||||
await tester.drag(find.text('3'), _kRowOffset);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(date, DateTime(2019, 1, 1, 16));
|
||||
|
||||
// 16:00 -> 4:00
|
||||
await tester.drag(find.text('PM'), -_kRowOffset);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(date, DateTime(2019, 1, 1, 4));
|
||||
|
||||
// 4:00 -> 3:00
|
||||
await tester.drag(find.text('4'), -_kRowOffset);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(date, DateTime(2019, 1, 1, 3));
|
||||
});
|
||||
|
||||
testWidgets('picker automatically scrolls the am/pm column when the hour column changes enough', (WidgetTester tester) async {
|
||||
DateTime date;
|
||||
await tester.pumpWidget(
|
||||
@ -542,25 +592,29 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
await tester.drag(find.text('11'), const Offset(0.0, -32.0));
|
||||
// 11:59 -> 12:59
|
||||
await tester.drag(find.text('11'), _kRowOffset);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(date, DateTime(2018, 1, 1, 12, 59));
|
||||
|
||||
await tester.drag(find.text('12'), const Offset(0.0, 32.0));
|
||||
// 12:59 -> 11:59
|
||||
await tester.drag(find.text('12'), -_kRowOffset);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(date, DateTime(2018, 1, 1, 11, 59));
|
||||
|
||||
await tester.drag(find.text('11'), const Offset(0.0, 64.0));
|
||||
// 11:59 -> 9:59
|
||||
await tester.drag(find.text('11'), -_kRowOffset * 2);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(date, DateTime(2018, 1, 1, 9, 59));
|
||||
|
||||
await tester.drag(find.text('9'), const Offset(0.0, -192.0));
|
||||
// 9:59 -> 15:59
|
||||
await tester.drag(find.text('9'), _kRowOffset * 6);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user