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

Flutter:按下按键时跳出Focus组件的实现方案

Flutter Focus组焦点跳转实现

需求

  • 按下方向键上/下:遍历当前Focus组内的FocusNode,切换到上一个/下一个节点
  • 按下Tab:跳出当前Focus组,切换到组外的下一个FocusNode
  • 按下Shift+Tab:跳出当前Focus组,切换到组外的上一个FocusNode

完整实现代码

Focus(
  onKey: (focusNode, event) {
    if (event is RawKeyDownEvent) {
      if (event.logicalKey == LogicalKeyboardKey.arrowDown) {
        focusNode.nextFocus();
        return KeyEventResult.handled;
      } else if (event.logicalKey == LogicalKeyboardKey.arrowUp) {
        focusNode.previousFocus();
        return KeyEventResult.handled;
      } else if (event.logicalKey == LogicalKeyboardKey.tab) {
        final hasShift = RawKeyboard.instance.keysPressed.contains(LogicalKeyboardKey.shiftLeft) ||
                          RawKeyboard.instance.keysPressed.contains(LogicalKeyboardKey.shiftRight);
        
        if (hasShift) {
          // 跳出到组外的上一个FocusNode
          focusNode.unfocus();
          FocusScope.of(focusNode.context!).previousFocus();
        } else {
          // 跳出到组外的下一个FocusNode
          focusNode.unfocus();
          FocusScope.of(focusNode.context!).nextFocus();
        }
        return KeyEventResult.handled;
      }
    }
    return KeyEventResult.ignored;
  },
  child: ... // 替换为你的组内子组件
)

实现说明

  1. 方向键逻辑保持原有逻辑,通过nextFocus()和previousFocus()遍历组内的焦点节点
  2. Tab/Shift+Tab处理:
    • 先调用focusNode.unfocus()释放当前组的焦点,确保焦点可以跳出当前组的作用域
    • 通过FocusScope.of(focusNode.context!)获取当前焦点作用域,调用previousFocus()或nextFocus()实现组外的焦点跳转
    • 同时判断左右Shift键,覆盖用户按下任意Shift键的场景
  3. 用event is RawKeyDownEvent替代runtimeType判断,更符合Dart的类型检查规范

内容的提问来源于stack exchange,提问作者murkr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:20:29