在这里插入图片描述

案例概述

本案例展示如何使用 showTimePicker 实现时间选择功能,包括单时间选择和时间范围选择。

核心概念

1. showTimePicker

  • 显示时间选择对话框;
  • 返回选中的 TimeOfDay
  • 支持 12 小时制和 24 小时制。

2. TimeOfDay

  • 表示一天中的时间;
  • 包含 hourminute
  • 提供 format() 方法格式化显示。

3. 时间操作

  • 获取小时和分钟:time.hourtime.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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐