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

Android平台Libgdx框架下三星键盘异常问题求助

解决三星HoneyBoard键盘下Libgdx视图上移异常问题

问题场景

在Libgdx 1.11.0游戏中,通过AndroidLauncher监听屏幕布局变化判断键盘状态,进而控制相机移动实现视图随键盘上移。正常设备上键盘弹出/隐藏仅触发一次对应状态,但搭载com.samsung.android.honeyboard/.service.HoneyBoardService的三星设备上,键盘弹出时会连续触发4次状态变更:HIDE、SHOW、SHOW、SHOW,导致文本框被遮挡,视图无法正确上移。

解决方案

1. 增加状态防抖与过滤

针对三星键盘弹出过程中的临时状态波动,通过记录上一次状态、延迟确认的方式过滤异常变更,只保留最终稳定状态:

// 新增变量记录上一次的键盘状态
private var lastKeyboardStatus: KeyboardStatus = KeyboardStatus.HIDE

override fun sizeChanged(width: Int, height: Int) {
    val heightRatio = Gdx.graphics.height / main.worldHeight
    val worldHeightChanged = height / heightRatio
    val currentKeyboardStatus = if (height == Gdx.graphics.height) KeyboardStatus.HIDE else KeyboardStatus.SHOW

    // 过滤重复状态,处理弹出时的临时HIDE异常
    if (currentKeyboardStatus != lastKeyboardStatus) {
        if (currentKeyboardStatus == KeyboardStatus.HIDE && lastKeyboardStatus == KeyboardStatus.SHOW) {
            // 延迟100ms确认状态,避免键盘弹出过程中的临时布局变化
            Handler(Looper.getMainLooper()).postDelayed({
                val latestVisibleFrame = Rect()
                window.decorView.getWindowVisibleDisplayFrame(latestVisibleFrame)
                val confirmedStatus = if (latestVisibleFrame.height() == Gdx.graphics.height) KeyboardStatus.HIDE else KeyboardStatus.SHOW
                if (confirmedStatus == currentKeyboardStatus) {
                    notifyStatusChange(confirmedStatus, worldHeightChanged)
                    lastKeyboardStatus = confirmedStatus
                }
            }, 100)
        } else {
            notifyStatusChange(currentKeyboardStatus, worldHeightChanged)
            lastKeyboardStatus = currentKeyboardStatus
        }
    }
}

private fun notifyStatusChange(status: KeyboardStatus, worldHeight: Float) {
    main.platformsObservable.notifyObservers(Triple(ObservableKeys.SCREEN_SIZE_CHANGED, status, worldHeight))
    log.error("SCREEN_SIZE_CHANGED, status = $status")
}

2. 改用Libgdx内置输入监听(推荐)

依赖Libgdx原生的输入处理API替代Android原生布局监听,兼容性更强:

// 在你的Libgdx游戏类中实现InputProcessor接口
public class MainGame implements InputProcessor {
    @Override
    public boolean keyboardFocusChanged(boolean focused) {
        if (focused) {
            // 文本框获得焦点,键盘即将弹出,执行视图上移逻辑
            adjustCamera(true);
        } else {
            // 文本框失去焦点,键盘即将隐藏,恢复视图位置
            adjustCamera(false);
        }
        return true;
    }

    private void adjustCamera(boolean isKeyboardShown) {
        // 这里根据键盘状态调整相机位置,可结合Android端传递的键盘高度数据
        // 例如:如果键盘显示,将相机向上偏移键盘对应的世界高度
    }
}

在AndroidLauncher初始化时,设置输入处理器:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val config = AndroidApplicationConfiguration()
    // 其他配置
    val mainGame = MainGame()
    initialize(mainGame, config)
    Gdx.input.setInputProcessor(mainGame)
}

3. 配置Android窗口属性

在AndroidManifest.xml中为游戏Activity添加窗口属性,强制系统在键盘弹出时调整布局:

<activity
    android:name=".AndroidLauncher"
    android:windowSoftInputMode="adjustResize|stateHidden">
    <!-- 其他Activity属性 -->
</activity>

adjustResize会让Activity窗口自动适配键盘高度,配合相机调整逻辑可进一步提升稳定性。

内容的提问来源于stack exchange,提问作者Jay N

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:50:28