mirror of
https://github.com/flutter/flutter.git
synced 2026-02-05 11:19:18 +08:00
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!
This commit is contained in:
parent
bfaa4a5bce
commit
0aec08c08d
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user