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
相关产品推荐
相关产品推荐

