调用setHideOrNot后Timer未取消仍执行问题求助
问题描述
调用setHideOrNot函数时明明已经执行了_timer?.cancel()操作来取消Timer,但1秒后该Timer仍会触发执行。我尝试了网上多种解决方案,却始终无法解决此问题,相关代码如下:
@override void addPressedToText(String pressedText) { if (authKeyboardInputController.text.length < 8) { String text = _authController.keyboardInputValue; _authController.keyboardInputValue = text + pressedText; // 实际文本值 if (_authController.isObscured) { // 除了最后一位字符外,其他字符会被隐藏显示给用户 authKeyboardInputController.text = _mainController.makeTextObscure(text: text) + pressedText; _timer?.cancel(); // 取消之前的timer _timer = Timer(const Duration(seconds: 1), () { authKeyboardInputController.text = _mainController.makeTextObscure( text: authKeyboardInputController.text); }); } else { authKeyboardInputController.text = _authController.keyboardInputValue; } setCursorPosition(); } } void setHideOrNot() { _timer?.cancel(); if (_authController.isObscured) { authKeyboardInputController.text = _mainController.makeTextObscure( text: _authController.keyboardInputValue); } else { authKeyboardInputController.text = _authController.keyboardInputValue; } }
解决方法
1. 增加状态标记阻断回调执行
核心思路是给Timer回调加前置判断,用布尔变量标记Timer是否已被取消,即使回调被触发也不会执行实际UI操作:
首先在类中添加状态变量:
bool _isTimerCanceled = false;
修改addPressedToText中的Timer创建逻辑:
_timer?.cancel(); _isTimerCanceled = false; // 重置取消标记 _timer = Timer(const Duration(seconds: 1), () { // 已取消则直接返回,不执行后续操作 if (_isTimerCanceled) return; authKeyboardInputController.text = _mainController.makeTextObscure( text: authKeyboardInputController.text); });
更新setHideOrNot函数,设置取消标记:
void setHideOrNot() { _timer?.cancel(); _isTimerCanceled = true; // 标记Timer已取消 if (_authController.isObscured) { authKeyboardInputController.text = _mainController.makeTextObscure( text: _authController.keyboardInputValue); } else { authKeyboardInputController.text = _authController.keyboardInputValue; } }
2. 确保Timer引用被彻底清空
调用cancel()后,Timer实例的引用可能仍会保留,引发意外问题,取消后将_timer置为null:
修改setHideOrNot:
void setHideOrNot() { _timer?.cancel(); _timer = null; // 清空Timer引用 if (_authController.isObscured) { authKeyboardInputController.text = _mainController.makeTextObscure( text: _authController.keyboardInputValue); } else { authKeyboardInputController.text = _authController.keyboardInputValue; } }
同时在addPressedToText创建新Timer前保持该逻辑:
_timer?.cancel(); _timer = null; _timer = Timer(const Duration(seconds: 1), () { authKeyboardInputController.text = _mainController.makeTextObscure( text: authKeyboardInputController.text); });
额外检查点
确认setHideOrNot的调用时机是在Timer创建后的1秒内,如果是1秒后才调用,Timer已经触发执行,cancel()自然不会生效。
内容的提问来源于stack exchange,提问作者Mr. Whestr
相关产品推荐
相关产品推荐

