Android系统中是否有一种方法可以检测软件(也就是Android。“软”)键盘在屏幕上可见吗?
当前回答
我把答案转换为kotlin,希望这对kotlin用户有帮助。
private fun checkKeyboardVisibility() {
var isKeyboardShowing = false
binding.coordinator.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
binding.coordinator.getWindowVisibleDisplayFrame(r)
val screenHeight = binding.coordinator.rootView.height
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
val keypadHeight = screenHeight - r.bottom
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
if (!isKeyboardShowing) {
isKeyboardShowing = true
}
} else {
// keyboard is closed
if (isKeyboardShowing) {
isKeyboardShowing = false
}
}
}
}
其他回答
使用androidx核心版本1.5.0-alpha02中的新特性WindowInsetsCompat,您可以轻松地检查软键盘的可见性,如下所示
摘自reddit评论
瓦尔View)。布尔keyboardIsVisible: 赢了 toWindowInsetsCompat (rootWindowInsets)。 isVisible (WindowInsetsCompat。。火车(型)
一些关于向后兼容性的说明,引用自发行说明
新功能 windowswinsetscompat api已经更新为平台中的api Android 11。这包括新的ime()插入类型,它允许 检查屏幕上键盘的可见性和大小。 一些关于ime()类型的警告,它在API 23+上工作非常可靠 当你的Activity使用adjuststresize窗口软输入模式时。 如果您使用的是adjustPan模式,它应该工作可靠 回到API 14。
参考文献
Twitter WindowInsetsCompat公告 Reddit的线程 Androidx Core 1.5.0-alpha02发布说明 WindowInsetsCompat文档
final View activityRootView = findViewById(R.id.rootlayout);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
activityRootView.getWindowVisibleDisplayFrame(r);
int screenHeight = activityRootView.getRootView().getHeight();
Log.e("screenHeight", String.valueOf(screenHeight));
int heightDiff = screenHeight - (r.bottom - r.top);
Log.e("heightDiff", String.valueOf(heightDiff));
boolean visible = heightDiff > screenHeight / 3;
Log.e("visible", String.valueOf(visible));
if (visible) {
Toast.makeText(LabRegister.this, "I am here 1", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(LabRegister.this, "I am here 2", Toast.LENGTH_SHORT).show();
}
}
});
我写了样本。
这个存储库可以帮助检测键盘状态,而无需假设“键盘应该超过屏幕的X部分”。
There is a direct method to find this out. And, it does not require the layout changes. So it works in immersive fullscreen mode, too. But, unfortunately, it does not work on all devices. So you have to test it with your device(s). The trick is that you try to hide or show the soft keyboard and capture the result of that try. If it works correct then the keyboard is not really shown or hidden. We just ask for the state. To stay up-to-date, you simply repeat this operation, e.g. every 200 milliseconds, using a Handler. The implementation below does just a single check. If you do multiple checks, then you should enable all the (_keyboardVisible) tests.
public interface OnKeyboardShowHide
{
void onShowKeyboard( Object param );
void onHideKeyboard( Object param );
}
private static Handler _keyboardHandler = new Handler();
private boolean _keyboardVisible = false;
private OnKeyboardShowHide _keyboardCallback;
private Object _keyboardCallbackParam;
public void start( OnKeyboardShowHide callback, Object callbackParam )
{
_keyboardCallback = callback;
_keyboardCallbackParam = callbackParam;
//
View view = getCurrentFocus();
if (view != null)
{
InputMethodManager imm = (InputMethodManager) getSystemService( Activity.INPUT_METHOD_SERVICE );
imm.hideSoftInputFromWindow( view.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY, _keyboardResultReceiver );
imm.showSoftInput( view, InputMethodManager.SHOW_IMPLICIT, _keyboardResultReceiver );
}
else // if (_keyboardVisible)
{
_keyboardVisible = false;
_keyboardCallback.onHideKeyboard( _keyboardCallbackParam );
}
}
private ResultReceiver _keyboardResultReceiver = new ResultReceiver( _keyboardHandler )
{
@Override
protected void onReceiveResult( int resultCode, Bundle resultData )
{
switch (resultCode)
{
case InputMethodManager.RESULT_SHOWN :
case InputMethodManager.RESULT_UNCHANGED_SHOWN :
// if (!_keyboardVisible)
{
_keyboardVisible = true;
_keyboardCallback.onShowKeyboard( _keyboardCallbackParam );
}
break;
case InputMethodManager.RESULT_HIDDEN :
case InputMethodManager.RESULT_UNCHANGED_HIDDEN :
// if (_keyboardVisible)
{
_keyboardVisible = false;
_keyboardCallback.onHideKeyboard( _keyboardCallbackParam );
}
break;
}
}
};
谢谢大家的回答,我是根据自己的情况想出来的
/**
* Add global layout listener to observe system keyboard visibility
*/
private void initObserverForSystemKeyboardVisibility() {
getRootView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//Add your own code here
Log.d("TEST_CODE", "isSystemKeyboardVisible:" + isSystemKeyboardVisible())
}
});
}
/**
* Check system keyboard visibility
* @return true if visible
*/
public boolean isSystemKeyboardVisible() {
try {
final InputMethodManager manager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
final Method windowHeightMethod = InputMethodManager.class.getMethod("getInputMethodWindowVisibleHeight");
final int height = (int) windowHeightMethod.invoke(manager);
return height > 0;
} catch (Exception e) {
return false;
}
}
推荐文章
- 如何允许所有网络连接类型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中复制一个文件?