You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 08:09:54