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

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.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:06:26