时间选择器 - OpenHarmony PC端Flutter方案
本文介绍了Flutter中时间选择功能的实现方法,重点讲解了showTimePicker组件的使用。主要内容包括:1)单时间选择和时间范围选择的基本实现;2)时间格式化和验证方法;3)时间差计算和时间段可视化;4)与表单集成的技巧。文章还提供了企业级应用中的高级功能,如时间约束、业务逻辑处理和快捷选择等,帮助开发者构建完整的时间选择系统。代码示例清晰展示了各种场景下的实现方式。
·
案例概述
本案例展示如何使用 showTimePicker 实现时间选择功能,包括单时间选择和时间范围选择。
核心概念
1. showTimePicker
- 显示时间选择对话框;
- 返回选中的
TimeOfDay; - 支持 12 小时制和 24 小时制。
2. TimeOfDay
- 表示一天中的时间;
- 包含
hour和minute; - 提供
format()方法格式化显示。
3. 时间操作
- 获取小时和分钟:
time.hour、time.minute; - 格式化显示:
time.format(context)。
代码详解
1. 单时间选择
Future<void> _selectTime(BuildContext context) async {
final TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: _selectedTime ?? TimeOfDay.now(),
);
if (picked != null) {
setState(() {
_selectedTime = picked;
});
}
}
2. 时间范围选择
Row(
children: [
Expanded(
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(_startTime?.format(context) ?? '开始'),
IconButton(
icon: Icon(Icons.access_time),
onPressed: () => _selectStartTime(context),
),
],
),
),
),
Expanded(
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(_endTime?.format(context) ?? '结束'),
IconButton(
icon: Icon(Icons.access_time),
onPressed: () => _selectEndTime(context),
),
],
),
),
),
],
)
3. 时间格式化
String formatTime(TimeOfDay time) {
return '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
}
高级话题:时间选择的高级应用
1. 时间验证
validator: (value) {
if (_selectedTime == null) return '请选择时间';
if (_selectedTime!.hour < 9 || _selectedTime!.hour > 17) {
return '请选择工作时间(9:00-17:00)';
}
return null;
}
2. 时间范围验证
if (_endTime.hour * 60 + _endTime.minute <= _startTime.hour * 60 + _startTime.minute) {
return '结束时间不能早于开始时间';
}
3. 时间快捷选择
Row(
children: [
ElevatedButton(
onPressed: () => _selectTime(TimeOfDay(hour: 9, minute: 0)),
child: Text('9:00'),
),
ElevatedButton(
onPressed: () => _selectTime(TimeOfDay(hour: 14, minute: 0)),
child: Text('14:00'),
),
ElevatedButton(
onPressed: () => _selectTime(TimeOfDay(hour: 18, minute: 0)),
child: Text('18:00'),
),
],
)
4. 时间计算
// 计算时间差(分钟)
int calculateMinutesDifference(TimeOfDay start, TimeOfDay end) {
return (end.hour * 60 + end.minute) - (start.hour * 60 + start.minute);
}
// 计算时间差(小时)
double calculateHoursDifference(TimeOfDay start, TimeOfDay end) {
return calculateMinutesDifference(start, end) / 60.0;
}
5. 时间显示的国际化
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
child: child!,
);
},
)
6. 时间选择与日期结合
DateTime combineDateAndTime(DateTime date, TimeOfDay time) {
return DateTime(date.year, date.month, date.day, time.hour, time.minute);
}
7. 时间段的可视化
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.blue.shade50,
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
Text('开始时间:${_startTime?.format(context)}'),
Text('结束时间:${_endTime?.format(context)}'),
Text('时长:${calculateHoursDifference(_startTime!, _endTime!).toStringAsFixed(1)} 小时'),
],
),
)
8. 时间选择的性能优化
缓存时间选择器的状态:
late final _timePickerState = TimePickerState();
void dispose() {
_timePickerState.dispose();
super.dispose();
}
9. 时间选择与表单集成
TextFormField(
readOnly: true,
decoration: InputDecoration(
suffixIcon: Icon(Icons.access_time),
),
onTap: () => _selectTime(context),
validator: (value) {
if (_selectedTime == null) return '请选择时间';
return null;
},
)
10. 时间选择的无障碍支持
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
// Flutter 会自动提供键盘导航支持
)
通过这些高级技巧,你可以构建出功能完整的时间选择系统。
高级话题:时间选择的企业级应用
1. 时间验证与约束
validator: (value) {
if (_selectedTime == null) return '请选择时间';
if (_selectedTime!.hour < 9 || _selectedTime!.hour > 17) {
return '请选择工作时间(9:00-17:00)';
}
return null;
}
2. 时间范围的业务逻辑
int calculateMinutesDifference(TimeOfDay start, TimeOfDay end) {
return (end.hour * 60 + end.minute) - (start.hour * 60 + start.minute);
}
double calculateHoursDifference(TimeOfDay start, TimeOfDay end) {
return calculateMinutesDifference(start, end) / 60.0;
}
3. 时间快捷选择
Row(
children: [
ElevatedButton(onPressed: () => _selectTime(TimeOfDay(hour: 9, minute: 0)), child: Text('9:00')),
ElevatedButton(onPressed: () => _selectTime(TimeOfDay(hour: 14, minute: 0)), child: Text('14:00')),
],
)
4. 时间与日期结合
DateTime combineDateAndTime(DateTime date, TimeOfDay time) {
return DateTime(date.year, date.month, date.day, time.hour, time.minute);
}
5. 时间的本地化
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
child: child!,
);
},
)
6. 时间的缓存与恢复
Future<void> _saveTimeSelection() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('selected_time', _selectedTime!.format(context));
}
7. 时间的键盘控制
Focus(
onKey: (node, event) {
if (event.isKeyPressed(LogicalKeyboardKey.arrowUp)) {
// 增加小时
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
},
child: TextField(...),
)
8. 时间的无障碍支持
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
// Flutter 会自动提供键盘导航支持
)
9. 时间段的可视化
Container(
padding: EdgeInsets.all(16),
child: Column(
children: [
Text('开始时间:${_startTime?.format(context)}'),
Text('结束时间:${_endTime?.format(context)}'),
Text('时长:${calculateHoursDifference(_startTime!, _endTime!).toStringAsFixed(1)} 小时'),
],
),
)
10. 时间的测试
test('时间差计算', () {
final start = TimeOfDay(hour: 9, minute: 0);
final end = TimeOfDay(hour: 17, minute: 0);
expect(calculateHoursDifference(start, end), 8.0);
});
通过这些企业级技巧,你可以构建出功能完整的时间管理系统。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)