我需要做一件非常简单的事情-找出软件键盘是否显示。这在Android中可行吗?
当前回答
我知道如何准确地确定键盘是否隐藏。
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
public int getNavigationBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
public boolean isKeyboardHidden() {
int delta = mRootView.getRootView().getHeight() - mRootView.getHeight() - getNavigationBarHeight() - getStatusBarHeight()
- getSupportActionBar().getHeight();
return delta <= 0;
}
这适用于平板电脑。当导航栏水平显示时。
其他回答
InputMethodManager有关于软键盘的信息。你从一个活动中获得它:
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))
你可以摆弄一下,看看它能告诉你什么。你可以用它来显示或隐藏软输入…
就计算机而言,这是永远的问题,但这个问题仍然令人难以置信地相关!
所以我把上面的答案结合起来,做了一些改进……
public interface OnKeyboardVisibilityListener {
void onVisibilityChanged(boolean visible);
}
public final void setKeyboardListener(final OnKeyboardVisibilityListener listener) {
final View activityRootView = ((ViewGroup) getActivity().findViewById(android.R.id.content)).getChildAt(0);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
private boolean wasOpened;
private final int DefaultKeyboardDP = 100;
// From @nathanielwolf answer... Lollipop includes button bar in the root. Add height of button bar (48dp) to maxDiff
private final int EstimatedKeyboardDP = DefaultKeyboardDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);
private final Rect r = new Rect();
@Override
public void onGlobalLayout() {
// Convert the dp to pixels.
int estimatedKeyboardHeight = (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, activityRootView.getResources().getDisplayMetrics());
// Conclude whether the keyboard is shown or not.
activityRootView.getWindowVisibleDisplayFrame(r);
int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
boolean isShown = heightDiff >= estimatedKeyboardHeight;
if (isShown == wasOpened) {
Log.d("Keyboard state", "Ignoring global layout change...");
return;
}
wasOpened = isShown;
listener.onVisibilityChanged(isShown);
}
});
}
对我有用:)
注意: 如果你注意到DefaultKeyboardDP不适合你的设备播放的值,并发表评论,让每个人都知道应该是什么值…最终我们将得到适合所有设备的正确值!
要了解更多细节,请查看Cyborg上的实现
这里99%的解决方案是基于IME窗口大小的概率,每个这样的解决方案都是一个sh…价值!
因为:
覆盖-来自用户应用程序或系统应用程序 IME没有最小尺寸,它可以占用100%的窗口大小,并且可以像开发人员实现的想象那样薄:) 模态窗口/多窗口 更多的人不了解IPC(例如:外部窗口或其内容检测)
所以猜它是输入法总是错误的-不要猜,一定要确定!!
@kevin-du是目前最好的解决方案,因为它的查询IMM的IME高度-但它说的方法是隐藏的API,所以使用它可能是危险的方式得到错误的“假阴性结果”-通过错误的开发使用。
视图#setOnApplyWindowInsetsListener可以用来获得窗口insets回调
public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener) {
getListenerInfo().mOnApplyWindowInsetsListener = listener;
}
//OnApplyWindowInsetsListener
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets);
boolean keyboardVisible = insets.isVisible(WindowInsets.Type.ime())可以给出可见性状态。
在使用上述大多数建议添加固定数字的解决方案时,我刚刚遇到了一个错误。
S4的dpi很高,导致导航栏的高度为100px,因此我的应用程序认为键盘一直是打开的。
所以,随着所有新的高分辨率手机的发布,我认为使用硬编码值从长远来看不是一个好主意。
在各种屏幕和设备上进行测试后,我发现一个更好的方法是使用百分比。 获取decorView和你的应用内容之间的差异,然后检查这个差异的百分比。 从我得到的统计数据来看,大多数导航栏(无论大小、分辨率等)将占据屏幕的3%到5%。如果键盘是打开的,它会占据屏幕的47%到55%。
作为结论,我的解决方案是检查是否差异超过10%,然后我假设它的键盘打开。
推荐文章
- 如何允许所有网络连接类型HTTP和HTTPS在Android(9)馅饼?
- Android加载JS包失败
- Android Studio, logcat在应用程序关闭后清理
- 在android中从上下文获取活动
- 无法解析主机"<URL here>"没有与主机名关联的地址
- getActivity()在Fragment函数中返回null
- 按钮背景是透明的
- 在Mac OS X上哪里安装Android SDK ?
- 我如何获得图像缩放功能?
- 在Android应用程序中显示当前时间和日期
- BottomSheetDialogFragment的圆角
- 在应用程序启动时出现“无法获得BatchedBridge,请确保您的bundle被正确打包”的错误
- 我如何改变默认对话框按钮的文本颜色在安卓5
- 更改单选按钮的圆圈颜色
- 如何在android中复制一个文件?