Flutter如何识别Google Glass上滑手势并阻止应用直接退出
Flutter适配Google Glass Enterprise Edition 2上滑手势捕获方案
Google Glass Enterprise Edition 2的上滑手势默认映射Android系统KEYCODE_MENU事件,Flutter引擎默认会消费这个事件的默认行为(触发应用退出/返回),且不会把该事件派发给Flutter层的RawKeyboardListener,这就是你之前用AbsorbPointer、Listener、WillPopScope等组件都收不到回调的核心原因。
你之前已经匹配正确的其余手势映射逻辑是可用的,只需要补全原生层拦截+Flutter层映射即可解决问题。
第一步:修改Android端MainActivity拦截系统默认按键逻辑
需要在原生Activity层拦截上滑对应的菜单键事件,阻断系统默认退出逻辑,再将事件正常派发给Flutter层。
如果你的项目使用Kotlin编写MainActivity,打开android/app/src/main/kotlin/[你的应用包名]/MainActivity.kt,替换为如下代码:
import io.flutter.embedding.android.FlutterActivity import android.view.KeyEvent class MainActivity: FlutterActivity() { override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { // 拦截上滑对应的KEYCODE_MENU事件,屏蔽系统默认行为 if (keyCode == KeyEvent.KEYCODE_MENU) { return true } return super.onKeyDown(keyCode, event) } override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { if (keyCode == KeyEvent.KEYCODE_MENU) { // 放行事件到Flutter层 return super.onKeyUp(keyCode, event); } return super.onKeyUp(keyCode, event); } }
如果你的项目使用Java编写MainActivity,打开android/app/src/main/java/[你的应用包名]/MainActivity.java,替换为如下代码:
import android.view.KeyEvent; import io.flutter.embedding.android.FlutterActivity; public class MainActivity extends FlutterActivity { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU) { return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU) { return super.onKeyUp(keyCode, event); } return super.onKeyUp(keyCode, event); } }
第二步:补全Flutter层上滑事件映射
KEYCODE_MENU在Flutter中对应LogicalKeyboardKey.menu常量,直接在你现有的_handleKeyEvent方法中补全判断分支即可:
void _handleKeyEvent(RawKeyEvent event) { if (event is RawKeyUpEvent && !event.isShiftPressed) { setState(() { if (event.logicalKey == LogicalKeyboardKey.goBack) { _message = 'Swipe down'; // 补全上滑事件判断 } else if (event.logicalKey == LogicalKeyboardKey.menu) { _message = 'Swipe up'; } else if (event.logicalKey == LogicalKeyboardKey.shiftLeft) { _message = 'Swipe left'; } else if (event.logicalKey == LogicalKeyboardKey.tab) { _message = 'Swipe right'; } else if (event.logicalKey == LogicalKeyboardKey.select) { _message = 'Tap'; } else { if (kReleaseMode) { _message = 'Pressed : 0x${event.logicalKey.keyId.toRadixString(16)}'; } else { _message = 'Pressed : ${event.logicalKey.debugName}'; } } }); } }
额外优化点
- 焦点保活:在State的
initState中添加自动获取焦点逻辑,避免切后台、页面跳转后按键监听失效:
@override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { _focusNode.requestFocus(); }); }
- 完整的Google Glass EE2手势与Flutter按键映射表可以直接复用,不需要额外调试:
- 左滑:
LogicalKeyboardKey.shiftLeft - 右滑:
LogicalKeyboardKey.tab - 触摸板点击:
LogicalKeyboardKey.select - 下滑:
LogicalKeyboardKey.goBack - 上滑:
LogicalKeyboardKey.menu
- 左滑:
- 注意:不要依赖WillPopScope拦截上滑退出,上滑触发的不是Flutter路由的返回事件,是Android系统级的按键默认行为,必须在原生Activity层拦截才能生效。
内容的提问来源于stack exchange,提问作者Mathilde G.
相关产品推荐
相关产品推荐

