Android系统中是否有一种方法可以检测软件(也就是Android。“软”)键盘在屏幕上可见吗?
当前回答
这对我很有用。也许这对于所有版本来说都是最好的方法。
这将是有效的,使键盘可见性的属性,并观察这个变化延迟,因为onGlobalLayout方法调用多次。此外,检查设备旋转和windowSoftInputMode是否为adjustNothing也很好。
boolean isKeyboardShowing = false;
void onKeyboardVisibilityChanged(boolean opened) {
print("keyboard " + opened);
}
// ContentView is the root view of the layout of this activity/fragment
contentView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
contentView.getWindowVisibleDisplayFrame(r);
int screenHeight = contentView.getRootView().getHeight();
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
int keypadHeight = screenHeight - r.bottom;
Log.d(TAG, "keypadHeight = " + keypadHeight);
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
if (!isKeyboardShowing) {
isKeyboardShowing = true
onKeyboardVisibilityChanged(true)
}
}
else {
// keyboard is closed
if (isKeyboardShowing) {
isKeyboardShowing = false
onKeyboardVisibilityChanged(false)
}
}
}
});
其他回答
@iWantScala的回答很棒,但不适合我 rootView.getRootView().getHeight()总是有相同的值
一种方法是定义两个变量
private int maxRootViewHeight = 0;
private int currentRootViewHeight = 0;
添加全局监听器
rootView.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
currentRootViewHeight = rootView.getHeight();
if (currentRootViewHeight > maxRootViewHeight) {
maxRootViewHeight = currentRootViewHeight;
}
}
});
然后检查
if (currentRootViewHeight >= maxRootViewHeight) {
// Keyboard is hidden
} else {
// Keyboard is shown
}
工作正常
可以使用showSoftInput()和hideSoftInput()的回调结果来检查键盘的状态。完整的细节和示例代码在
https://rogerkeays.com/how-to-check-if-the-software-keyboard-is-shown-in-android
如你所知,android软件的键盘只有在有可能的输入事件时才可见。换句话说,只有当EditText被聚焦时,键盘才可见。这意味着你可以通过使用OnFocusChangeListener获得键盘是否可见。
//Declare this Globally
public boolean isKeyBoardVisible = false;
//In OnCreate *[For Activity]*, OnCreateView *[For Fragment]*
text_send.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus)
isKeyBoardVisible = true;
else
isKeyBoardVisible = false;
}
});
现在你可以在类的任何地方使用isKeyBoardVisible变量来获取键盘是否打开。这对我来说很有效。
注意:当使用InputMethodManager以编程方式打开键盘时,这个过程不起作用,因为它不调用OnFocusChangeListener。
谢谢大家的回答,我是根据自己的情况想出来的
/**
* 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;
}
}
这应该工作,如果你需要检查键盘状态:
fun Activity.isKeyboardOpened(): Boolean {
val r = Rect()
val activityRoot = getActivityRoot()
val visibleThreshold = dip(UiUtils.KEYBOARD_VISIBLE_THRESHOLD_DP)
activityRoot.getWindowVisibleDisplayFrame(r)
val heightDiff = activityRoot.rootView.height - r.height()
return heightDiff > visibleThreshold;
}
fun Activity.getActivityRoot(): View {
return (findViewById<ViewGroup>(android.R.id.content)).getChildAt(0);
}
UiUtils的地方。KEYBOARD_VISIBLE_THRESHOLD_DP = 100, dip()是一个anko函数,转换dpToPx:
fun dip(value: Int): Int {
return (value * Resources.getSystem().displayMetrics.density).toInt()
}
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件