软键盘显示时如何完整展示Options Menu?
我有一个带有Options Menu的Activity,通常软键盘处于显示状态。当用户打开Options Menu时,菜单仅显示到软键盘位置,用户可能不会意识到还有更多选项。我尝试在onPrepareOptionsMenu中隐藏软键盘,但即使在此处隐藏,仍仅能显示部分Options Menu。

截图展示了以下三种场景:
- 用户关闭软键盘后打开Options Menu的效果。
- 软键盘显示时用户打开Options Menu的效果。
- 在
onPrepareOptionsMenu()中关闭软键盘后的效果。
问题根源
直接在onPrepareOptionsMenu中隐藏软键盘无效,是因为系统绘制Options Menu时,会基于当前窗口的可用高度计算菜单布局。而隐藏软键盘是异步操作,onPrepareOptionsMenu执行时键盘还未完全收起,窗口高度未更新,菜单已经按照有键盘的状态完成了布局,后续键盘收起也不会触发菜单重新调整。
解决方案
通过重写openOptionsMenu()方法,先隐藏软键盘,等待窗口布局更新完成后再打开菜单,确保系统能获取到正确的窗口可用高度:
- 先写一个通用的隐藏软键盘工具方法:
private void hideSoftKeyboard() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); View focusedView = getCurrentFocus(); if (focusedView != null) { imm.hideSoftInputFromWindow(focusedView.getWindowToken(), 0); } }
- 重写
openOptionsMenu():
@Override public void openOptionsMenu() { hideSoftKeyboard(); // 将打开菜单的操作post到主线程消息队列,等待窗口布局调整完成后执行 getWindow().getDecorView().post(new Runnable() { @Override public void run() { super.openOptionsMenu(); } }); }
备选方案
如果重写openOptionsMenu不适用,也可以在onPrepareOptionsMenu中强制窗口重新布局并刷新菜单:
@Override public boolean onPrepareOptionsMenu(Menu menu) { hideSoftKeyboard(); // 请求窗口重新布局 getWindow().getDecorView().requestLayout(); // 刷新菜单,让系统重新计算布局 invalidateOptionsMenu(); return super.onPrepareOptionsMenu(menu); }
内容的提问来源于stack exchange,提问作者Dana Bell
相关产品推荐
相关产品推荐

