Android系统中是否有一种方法可以检测软件(也就是Android。“软”)键盘在屏幕上可见吗?
当前回答
我用这个作为基础:https://rogerkeays.com/how-to-check-if-the-software-keyboard-is-shown-in-android
/**
* To capture the result of IMM hide/show soft keyboard
*/
public class IMMResult extends ResultReceiver {
public int result = -1;
public IMMResult() {
super(null);
}
@Override
public void onReceiveResult(int r, Bundle data) {
result = r;
}
// poll result value for up to 500 milliseconds
public int getResult() {
try {
int sleep = 0;
while (result == -1 && sleep < 500) {
Thread.sleep(100);
sleep += 100;
}
} catch (InterruptedException e) {
Log.e("IMMResult", e.getMessage());
}
return result;
}
}
然后写了这个方法:
public boolean isSoftKeyboardShown(InputMethodManager imm, View v) {
IMMResult result = new IMMResult();
int res;
imm.showSoftInput(v, 0, result);
// if keyboard doesn't change, handle the keypress
res = result.getResult();
if (res == InputMethodManager.RESULT_UNCHANGED_SHOWN ||
res == InputMethodManager.RESULT_UNCHANGED_HIDDEN) {
return true;
}
else
return false;
}
然后你可以用它来测试所有可能打开软键盘的字段(EditText, AutoCompleteTextView等):
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
if(isSoftKeyboardShown(imm, editText1) | isSoftKeyboardShown(imm, autocompletetextview1))
//close the softkeyboard
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
当然不是一个理想的解决方案,但它可以完成工作。
其他回答
所以,在花了很长一段时间摆弄accesessibilityservices、窗口嵌入、屏幕高度检测等之后,我想我找到了一种方法来做到这一点。
免责声明:它在Android中使用了一个隐藏的方法,这意味着它可能不一致。然而,在我的测试中,它似乎有效。
该方法是InputMethodManager#getInputMethodWindowVisibleHeight(),它自Lollipop(5.0)以来就存在了。
调用它将返回当前键盘的高度(以像素为单位)。理论上,键盘不应该是0像素高,所以我做了一个简单的高度检查(在Kotlin中):
val imm by lazy { context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager }
if (imm.inputMethodWindowVisibleHeight > 0) {
//keyboard is shown
else {
//keyboard is hidden
}
当我调用隐藏方法时,我使用Android隐藏API来避免反射(我为我开发的应用程序做了很多,这些应用程序主要是hack /tuner应用程序),但这应该也是可能的反射:
val imm by lazy { context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager }
val windowHeightMethod = InputMethodManager::class.java.getMethod("getInputMethodWindowVisibleHeight")
val height = windowHeightMethod.invoke(imm) as Int
//use the height val in your logic
非常容易
1. 把id放在根视图上
rootView只是一个视图指向我的根视图在这种情况下,一个相对布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/addresses_confirm_root_view"
android:background="@color/WHITE_CLR">
2. 在Activity中初始化根视图:
RelativeLayout rootView = (RelativeLayout) findViewById(R.id.addresses_confirm_root_view);
3.使用getViewTreeObserver()检测键盘是否打开或关闭
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight();
if (heightDiff > 100) { // Value should be less than keyboard's height
Log.e("MyActivity", "keyboard opened");
} else {
Log.e("MyActivity", "keyboard closed");
}
}
});
你可以在androidx上使用WindowInsetsCompat。Core(版本1.5.0-rc01)。 此代码将从API 21及以上版本工作。Kotlin代码示例:
ViewCompat.setOnApplyWindowInsetsListener(root) { v, insets ->
val isKeyboardVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
if (isKeyboardVisible) {
}
}
root是Activity的根视图。
更新
今天我正在寻找如何检测键盘可见性。起初,这个代码不起作用。所以我不得不:
添加android:windowSoftInputMode=" adjuststresize "到我的AndroidManifest.xml文件:
xml
<activity android:name="com.soumicslabs.activitykt.StartActivity"
android:theme="@style/AccountKitTheme.Default"
android:configChanges="orientation|screenSize"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"
/>
在您的活动中,设置WindowCompat。setDecorFitsSystemWindows(window, false),这告诉android我们想手动处理的东西/不想使用系统默认值:
val window = this.window
WindowCompat.setDecorFitsSystemWindows(window, false) // <-- this tells android not to use system defaults, so we have to setup quite a lot of behaviors manually
最后,设置你的onApplyWindowInsetsListener:
val callBack = OnApplyWindowInsetsListener { view, insets ->
val imeHeight = insets?.getInsets(WindowInsetsCompat.Type.ime())?.bottom?:0
Log.e("tag", "onKeyboardOpenOrClose imeHeight = $imeHeight")
// todo: logic
val isKeyboardVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
if (isKeyboardVisible) {
// do something
}else{
// do something else
}
insets?: WindowInsetsCompat(null)
}
ViewCompat.setOnApplyWindowInsetsListener(mainContainer, callBack)
这对我很管用。
这对我很有用。也许这对于所有版本来说都是最好的方法。
这将是有效的,使键盘可见性的属性,并观察这个变化延迟,因为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)
}
}
}
});
我也遇到过类似的问题。我需要对屏幕上的Enter按钮做出反应(这隐藏了键盘)。在这种情况下,你可以订阅键盘打开的文本视图的OnEditorAction -如果你有多个可编辑框,那么就订阅所有的文本视图。
在你的活动中,你可以完全控制键盘,所以如果你监听所有打开和关闭事件,你就不会面临键盘是否打开的问题。
推荐文章
- 警告: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文件