Flutter如何实现TimePicker常显、获取选中时间及修改按钮功能
解决方案
你当前使用的TimePickerDialog是弹窗专用组件,本身设计为临时弹出交互后销毁,未对外暴露时间变更回调与底部按钮自定义能力,不适合常驻页面的需求,可按以下方案实现:
实现步骤
- 改用Flutter 3.10+官方提供的独立
TimePicker组件,该组件专门用于嵌入页面常驻展示,自带onTimeChanged回调可实时获取用户选择的时间 - 自行在页面中添加确认、取消按钮,完全自定义交互逻辑
完整示例代码
import 'package:flutter/material.dart'; class AddAlarmPage extends StatefulWidget { const AddAlarmPage({super.key}); @override State<AddAlarmPage> createState() => _AddAlarmPageState(); } class _AddAlarmPageState extends State<AddAlarmPage> { // 存储用户选中的时间 TimeOfDay _selectedTime = TimeOfDay.now(); // 存储选中的日期,适配你原有逻辑 DateTime _selectedDate = DateTime.now(); String getDate() { return "${_selectedDate.year}年${_selectedDate.month}月${_selectedDate.day}日"; } void pickDate(BuildContext context) async { final pickedDate = await showDatePicker( context: context, initialDate: _selectedDate, firstDate: DateTime.now(), lastDate: DateTime.now().add(const Duration(days: 365)), ); if (pickedDate != null) { setState(() { _selectedDate = pickedDate; }); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xff2E2E42), appBar: PreferredSize( preferredSize: const Size.fromHeight(50), child: AppBar(title: const Text("Add Alarm"), backgroundColor: const Color(0xff2E2E42), elevation: 0,) ), body: Column( children: [ // 常驻展示的时间选择器,替换原来的TimePickerDialog TimePicker( initialTime: _selectedTime, onTimeChanged: (newTime) { // 实时获取用户修改的时间 setState(() { _selectedTime = newTime; }); }, // 适配你的深色背景样式 style: TimePickerStyle( backgroundColor: const Color(0xff2E2E42), hourMinuteTextStyle: const TextStyle(color: Colors.white, fontSize: 48), dialHandColor: Colors.blueAccent, dialBackgroundColor: const Color(0xff3A3A52), ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 42.0), child: Column( children: [ MaterialButton( onPressed: () => pickDate(context), child: Column( children: [ Center( child: Text( getDate(), style: const TextStyle( color: Colors.white, fontSize: 30, ), ), ), ], ), ), const SizedBox(height: 32), // 自定义的底部按钮,完全自己控制逻辑 Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ TextButton( onPressed: () { // 自定义取消逻辑,比如返回上一页/重置时间 setState(() { _selectedTime = TimeOfDay.now(); }); }, child: const Text("取消", style: TextStyle(color: Colors.grey, fontSize: 18)), ), ElevatedButton( onPressed: () { // 自定义确认逻辑,比如保存闹钟信息 final hour = _selectedTime.hour.toString().padLeft(2, '0'); final minute = _selectedTime.minute.toString().padLeft(2, '0'); debugPrint("用户选中的时间是:$hour:$minute,选中的日期是${getDate()}"); // 后续你自己的保存、跳转逻辑 }, style: ElevatedButton.styleFrom(backgroundColor: Colors.blueAccent), child: const Text("确认", style: TextStyle(color: Colors.white, fontSize: 18)), ), ], ) ], ), ), ], ), ); } }
低版本Flutter兼容方案
如果你使用的Flutter版本低于3.10,没有独立的TimePicker组件,可以通过以下方式实现:
- 复制
TimePickerDialog的源码到本地,修改源码暴露onTimeChanged回调与底部按钮的自定义参数 - 使用第三方时间选择库的嵌入式组件实现需求
内容的提问来源于stack exchange,提问作者Skrrubs
相关产品推荐
相关产品推荐

