Android TV Leanback 环境下检测软键盘是否可见的方法有哪些?
Android TV 软键盘显示/隐藏状态检测解决方案
移动端常规的
ViewTreeObserver.OnGlobalLayoutListener监听布局高度变化、windowSoftInputMode结合adjustResize判定的方案,在Android TV环境失效的核心原因是:大部分TV端输入法采用悬浮窗口方案,弹出时不会挤压Activity的根布局高度,因此不会触发布局变化回调。
方案1:基于InputMethodManager的状态检测(优先推荐)
该方案兼容性覆盖绝大多数Android TV系统版本,实现成本最低
- API 31及以上版本直接调用官方原生监听:
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager // 组件销毁时需主动调用removeOnSoftInputVisibilityChangedListener注销,避免内存泄漏 imm.addOnSoftInputVisibilityChangedListener(mainExecutor) { isVisible -> // 直接获取键盘显示状态 Log.d("KeyboardState", "键盘是否显示:$isVisible") } - API 31以下版本通过反射读取隐藏字段判定:
低版本系统隐藏了键盘状态变量,可通过反射读取,可搭配200ms~500ms的低频率轮询实现状态实时同步:
注意:该频率的轮询不会产生明显的性能开销,完全满足TV端交互的实时性要求public static boolean isKeyboardShown(InputMethodManager imm) { try { Field field = InputMethodManager.class.getDeclaredField("mIsInputShown"); field.setAccessible(true); return field.getBoolean(imm); } catch (Exception e) { e.printStackTrace(); return false; } }
方案2:基于窗口焦点变化的无反射检测
如果出于安全考虑禁止使用反射逻辑,可以通过窗口焦点变化判定状态,该方案不需要申请额外权限
Android TV软键盘弹出时会抢占窗口焦点,可结合输入法激活状态联合判定:
override fun onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager val isInputActive = imm.isAcceptingText // 输入法处于激活状态+当前Activity失去焦点,即可判定为键盘弹出 val isKeyboardShown = !hasFocus && isInputActive }
通用注意事项
- 不要依赖布局尺寸变化的常规移动端方案,90%以上的TV端输入法采用悬浮窗口逻辑,不会修改Activity布局大小
- 所有监听逻辑需要和组件生命周期绑定,销毁时及时注销避免内存泄漏
- 部分深度定制的第三方TV ROM如果出现兼容问题,优先选用方案1的反射逻辑,覆盖范围更广
内容的提问来源于stack exchange,提问作者sadat
相关产品推荐
相关产品推荐

