使用showTimePicker组件触发'!_debugLocked': is not true错误求助
问题解决:showTimePicker触发'!_debugLocked'错误及抽离函数问题
错误原因分析
- '!_debugLocked': is not true:TextFormField的
onTap触发时,组件会自动尝试获取焦点,而showTimePicker弹窗会触发路由状态变化,两者的焦点管理冲突,触发调试断言错误。 - 抽离函数时报void错误:抽离的函数返回值为
void,但如果调用方式错误(比如直接将函数返回值赋值给onTap),会导致类型不匹配。
解决方案
方案1:直接在onTap中修正逻辑
在调用showTimePicker前先取消文本字段的焦点,并使用async/await处理异步弹窗:
TextFormField( onTap: () async { // 先取消焦点,避免路由与焦点管理冲突 FocusScope.of(context).unfocus(); final selectedTime = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); if (selectedTime != null) { // 将选中时间格式化后赋值给controller datecontroller.text = selectedTime.format(context); } }, controller: datecontroller, keyboardType: TextInputType.text, onFieldSubmitted: (String value) { print(value); }, validator: (String? value) { if (value!.isEmpty) { return 'date can\'t be empty'; } return null; }, );
方案2:抽离到外部函数
定义无返回值的异步函数,通过箭头函数传递给onTap:
// 抽离的时间选择函数 void _showTimePicker(BuildContext context, TextEditingController controller) async { FocusScope.of(context).unfocus(); final selectedTime = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); if (selectedTime != null) { controller.text = selectedTime.format(context); } } // TextFormField使用示例 TextFormField( onTap: () => _showTimePicker(context, datecontroller), controller: datecontroller, keyboardType: TextInputType.text, onFieldSubmitted: (String value) { print(value); }, validator: (String? value) { if (value!.isEmpty) { return 'date can\'t be empty'; } return null; }, );
关键要点
- 必须通过
FocusScope.of(context).unfocus()提前取消焦点,解决路由与焦点的冲突问题。 showTimePicker是异步方法,需用async/await等待用户选择结果,再更新文本控制器。- 抽离函数时,确保函数为
void类型,通过() => 函数名()的方式传递给onTap,符合VoidCallback的类型要求。
内容的提问来源于stack exchange,提问作者murtadha
相关产品推荐
相关产品推荐

