OpenGL NativeActivity中EditText回车键失效与OpenGL渲染停滞问题求助
解决方案:OpenGL NativeActivity中EditText的回车响应与渲染兼容问题
方案一:使用addContentView让EditText支持多行与回车键
问题根源
默认EditText为单行模式,且NativeActivity底层可能拦截回车键事件;未配置多行输入属性导致软键盘回车键无法触发换行。
具体实现
修改EditText初始化代码,添加多行配置并确保按键事件被正确消费:
// 创建EditText并配置多行属性 EditText editText = new EditText(activity); editText.setVisibility(View.VISIBLE); editText.setFocusable(true); editText.setFocusableInTouchMode(true); // 开启多行输入 editText.setSingleLine(false); editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE); // 设置软键盘回车键为换行(而非完成) editText.setImeOptions(EditorInfo.IME_FLAG_NO_ENTER_ACTION); // 监听回车键事件 editText.setOnKeyListener((v, keyCode, event) -> { if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { // 插入换行符 Editable editable = editText.getText(); int start = editText.getSelectionStart(); int end = editText.getSelectionEnd(); editable.replace(start, end, "\n"); return true; // 消费事件,避免被Native层拦截 } return false; }); // 添加到Activity内容视图 WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.height = WindowManager.LayoutParams.WRAP_CONTENT; activity.addContentView(editText, params); // 弹出软键盘 editText.requestFocus(); InputMethodManager imm = (InputMethodManager) activity.getSystemService(INPUT_METHOD_SERVICE); imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
额外处理
若Native层仍拦截按键事件,在NativeActivity的Java层重写dispatchKeyEvent,优先让EditText处理事件:
@Override public boolean dispatchKeyEvent(KeyEvent event) { View focusedView = getCurrentFocus(); if (focusedView instanceof EditText && focusedView.dispatchKeyEvent(event)) { return true; } return super.dispatchKeyEvent(event); }
方案二:使用WindowManager.addView时保持OpenGL正常渲染
问题根源
直接添加顶级View会覆盖OpenGL的SurfaceView,或导致SurfaceView失焦/销毁,中断Native层渲染循环。
具体实现
调整WindowManager参数,让EditText作为应用内浮动面板存在,不干扰SurfaceView:
// 创建EditText(多行配置参考方案一) EditText editText = new EditText(activity); editText.setVisibility(View.VISIBLE); editText.setFocusable(true); editText.setFocusableInTouchMode(true); editText.setSingleLine(false); editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE); editText.setImeOptions(EditorInfo.IME_FLAG_NO_ENTER_ACTION); // 配置WindowManager参数 WindowManager.LayoutParams params = new WindowManager.LayoutParams(); // API 26+用TYPE_APPLICATION_OVERLAY,低版本用TYPE_APPLICATION_PANEL if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; } else { params.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; } params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.height = WindowManager.LayoutParams.WRAP_CONTENT; // 允许EditText获焦,同时不阻塞SurfaceView事件 params.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; params.format = PixelFormat.TRANSLUCENT; // 背景透明,避免遮挡OpenGL内容 // 添加到WindowManager activity.getWindowManager().addView(editText, params); // 弹出软键盘 editText.requestFocus(); InputMethodManager imm = (InputMethodManager) activity.getSystemService(INPUT_METHOD_SERVICE); imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
Native层渲染保障
在Native层ANativeActivity_onWindowFocusChanged回调中,不要因失焦停止渲染:
void ANativeActivity_onWindowFocusChanged(ANativeActivity* activity, int hasFocus) { // 注释或移除原停止渲染的逻辑,保持OpenGL循环运行 }
内容的提问来源于stack exchange,提问作者Mike Weir
相关产品推荐
相关产品推荐

