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

Flutter监听键盘事件仅在keyDown阶段触发、忽略keyUp事件的实现问题

问题解决方法

RawKeyboardListener的onKey回调会在按键按下、按键抬起两个阶段均触发,未做阶段过滤就会出现一次按键操作触发两次逻辑的问题。

核心修改点
  • 给判断条件添加event is RawKeyDownEvent类型校验,仅在按键按下阶段执行业务逻辑
  • 修复原代码中print(down)缺少字符串引号的语法错误
完整修改后代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';  // 用于按键匹配对比

class MyWidget extends StatefulWidget {
  const MyWidget({super.key});

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final FocusNode focusNode = FocusNode();  // 跟踪组件焦点状态的凭证,只有持焦组件可接收键盘事件

  @override
  Widget build(BuildContext context) {
    FocusScope.of(context).requestFocus(focusNode); // 主动给当前组件分配焦点,加载完成后无需点击即可响应按键
    return Scaffold(
      appBar: AppBar(),
      body: RawKeyboardListener(
        autofocus: true,
        focusNode: focusNode,   // 绑定焦点节点
        onKey: (RawKeyEvent event) {
          // 仅匹配按下向下方向键的事件
          if (event is RawKeyDownEvent && event.data.logicalKey == LogicalKeyboardKey.arrowDown) {
            print("down");
          }
        },
        child: GridView.builder(
          physics: const NeverScrollableScrollPhysics(),
          itemCount: 300,
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 30),
          itemBuilder: (BuildContext context, int index) {
            return Container(
              padding: const EdgeInsets.all(5.0),
              color: Colors.grey,
            );
          },
        ),
      ),
    );
  }
}
补充说明
  • FocusNode:用于跟踪组件的焦点状态,只有持有焦点的组件才能接收到系统分发的键盘事件,相当于给当前RawKeyboardListener分配接收键盘事件的身份标识
  • FocusScope.of(context).requestFocus(focusNode):主动将焦点分配给绑定了当前focusNode的组件,页面加载完成后无需用户手动点击组件区域即可直接响应键盘事件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:06:01