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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 05:54:55