Unverified Commit 0aec08c0 authored by Darren Austin's avatar Darren Austin Committed by GitHub

TimePicker moves to minute mode after hour selection (#31566)

Adds a feature of the native Android Time Picker to our Material Time Picker. When the user selects an hour, it automatically switches to minute mode.

This is a merging of two pull requests:

Code changes from @sdolski #24677
Tests from @lucaslcode #29876

Thanks to both of you for your contributions!
parent bfaa4a5b
......@@ -1000,12 +1000,16 @@ class _Dial extends StatefulWidget {
@required this.mode,
@required this.use24HourDials,
@required this.onChanged,
}) : assert(selectedTime != null);
@required this.onHourSelected,
}) : assert(selectedTime != null),
assert(mode != null),
assert(use24HourDials != null);
final TimeOfDay selectedTime;
final _TimePickerMode mode;
final bool use24HourDials;
final ValueChanged<TimeOfDay> onChanged;
final VoidCallback onHourSelected;
@override
_DialState createState() => _DialState();
......@@ -1169,6 +1173,11 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
_position = null;
_center = null;
_animateTo(_getThetaForTime(widget.selectedTime));
if (widget.mode == _TimePickerMode.hour) {
if (widget.onHourSelected != null) {
widget.onHourSelected();
}
}
}
void _handleTapUp(TapUpDetails details) {
......@@ -1183,6 +1192,9 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
} else {
_announceToAccessibility(context, localizations.formatDecimal(newTime.hourOfPeriod));
}
if (widget.onHourSelected != null) {
widget.onHourSelected();
}
} else {
_announceToAccessibility(context, localizations.formatDecimal(newTime.minute));
}
......@@ -1522,6 +1534,12 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
});
}
void _handleHourSelected() {
setState(() {
_mode = _TimePickerMode.minute;
});
}
void _handleCancel() {
Navigator.pop(context);
}
......@@ -1547,6 +1565,7 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
use24HourDials: use24HourDials,
selectedTime: _selectedTime,
onChanged: _handleTimeChanged,
onHourSelected: _handleHourSelected,
),
),
);
......
......@@ -134,6 +134,39 @@ void _tests() {
expect(result.hour, equals(9));
});
testWidgets('tap-select switches from hour to minute', (WidgetTester tester) async {
TimeOfDay result;
final Offset center = await startPicker(tester, (TimeOfDay time) { result = time; });
final Offset hour6 = Offset(center.dx, center.dy + 50.0); // 6:00
final Offset min45 = Offset(center.dx - 50.0, center.dy); // 45 mins (or 9:00 hours)
await tester.tapAt(hour6);
await tester.pump(const Duration(milliseconds: 50));
await tester.tapAt(min45);
await finishPicker(tester);
expect(result, equals(const TimeOfDay(hour: 6, minute: 45)));
});
testWidgets('drag-select switches from hour to minute', (WidgetTester tester) async {
TimeOfDay result;
final Offset center = await startPicker(tester, (TimeOfDay time) { result = time; });
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
final Offset hour6 = Offset(center.dx, center.dy + 50.0);
final Offset hour9 = Offset(center.dx - 50.0, center.dy);
TestGesture gesture = await tester.startGesture(hour6);
await gesture.moveBy(hour9 - hour6);
await gesture.up();
await tester.pump(const Duration(milliseconds: 50));
gesture = await tester.startGesture(hour6);
await gesture.moveBy(hour3 - hour6);
await gesture.up();
await finishPicker(tester);
expect(result, equals(const TimeOfDay(hour: 9, minute: 15)));
});
group('haptic feedback', () {
const Duration kFastFeedbackInterval = Duration(milliseconds: 10);
const Duration kSlowFeedbackInterval = Duration(milliseconds: 200);
......
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