Flutter中RawKeyboardListener长按中心按钮重复触发问题求助
解决RawKeyboardListener长按遥控器按键重复触发的问题
在使用RawKeyboardListener实现电视遥控器按键控制时,长按中心按钮(keyCode 23)会重复执行对应功能,我们可以通过维护按键的按下状态来实现仅响应单次按压的需求。
修改方案
核心思路是记录当前处于按下状态的按键,仅在首次按下时触发功能,按键松开后清除记录,以此避免长按重复触发。由于需要维护状态,需将原StatelessWidget改为StatefulWidget:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class RawKeyboardListenerWidget extends StatefulWidget { final Widget child; final FocusNode focusNode; final void Function(int) remoteControlKeys; const RawKeyboardListenerWidget({ Key? key, required this.child, required this.focusNode, required this.remoteControlKeys, }) : super(key: key); @override State<RawKeyboardListenerWidget> createState() => _RawKeyboardListenerWidgetState(); } class _RawKeyboardListenerWidgetState extends State<RawKeyboardListenerWidget> { // 存储当前处于按下状态的按键code final Set<int> _activePressedKeys = {}; @override Widget build(BuildContext context) { return RawKeyboardListener( focusNode: widget.focusNode, onKey: (RawKeyEvent event) { if (event.data is RawKeyEventDataAndroid) { final keyData = event.data as RawKeyEventDataAndroid; final keyCode = keyData.keyCode; if (event is RawKeyDownEvent) { // 仅当按键未被标记为按下时,才执行逻辑 if (!_activePressedKeys.contains(keyCode)) { _activePressedKeys.add(keyCode); widget.remoteControlKeys(keyCode); if (keyCode == 23) { //_handleCenterOrEnterKeyPress(); } else if (keyCode == 20) { //_handleDownKeyPress(); } else if (keyCode == 19) { //_handleUpKeyPress(); } else if (keyCode == 22) { //_handleRightKeyPress(); } else if (keyCode == 21) { //_handleLeftKeyPress(); } } } else if (event is RawKeyUpEvent) { // 按键松开时,移除标记 _activePressedKeys.remove(keyCode); } } }, child: widget.child, ); } }
关键逻辑说明
- 使用
_activePressedKeys集合跟踪当前按下的按键,确保每个按键仅在首次按下时触发一次功能 - 当收到
RawKeyDownEvent时,先检查按键是否已在集合中:不在则执行逻辑并加入集合,已存在则跳过(对应长按重复触发的情况) - 收到
RawKeyUpEvent时,将按键从集合中移除,保证下次按压能正常响应
内容的提问来源于stack exchange,提问作者Mohammed Helewa
相关产品推荐
相关产品推荐

