首页 > 解决方案 > 如何在Activity的第一个布局之前关闭另一个应用程序打开的挥之不去的键盘?

问题描述

有很多答案解释了如何关闭 Android 的软键盘(例如这个),但他们都假设键盘是从您自己的应用程序中打开的,或者您已经有可以获得焦点的视图,从而胜过需要以前的应用程序。在 Android 的InputMethodManager类中,关闭由另一个应用程序打开的键盘的请求被拒绝,并且调用hideSoftInputFromWindow()返回 false。

我团队的一位开发人员创建了一个扩展方法Activity,只要键盘状态发生变化,它就会调用一个代码块。因为 Android 不会自行触发键盘显示/隐藏事件(这很荒谬),所以通常的做法是检测到Activity根布局高度的降低,并假设这意味着键盘已打开。(注意:这仅适用于windowSoftInputMode="adjustResize"。)此扩展方法,旨在被调用onCreate(),在调用它时记录根布局的高度,并注意随后的高度变化。如果布局的高度变小,则假定已显示键盘。如果它变得更大,则假定键盘已隐藏。虽然这种非确定性的 hack 很不幸,但它可能很有用,只要您不依赖 100% 的准确度。

不幸的是,它在这种情况下不起作用:

  1. 用户在另一个应用程序中启动,键盘打开
  2. 用户从我的应用中点击通知
  3. 我的应用程序打开(冷启动),键盘仍从其他应用程序打开
  4. 当onCreate()调用扩展方法时,我的Activity根布局的高度已经反映了键盘打开的情况,打破了键盘打开时看着它变短的概念

虽然可能有一些方法可以改进逻辑以使其更健壮,但我真正想做的是可靠地关闭“外来”键盘,这会影响我对应用程序高度的基线测量。但是我已经尝试windowSoftInputMode="stateHidden"在我的AndroidManifest.xml文件中设置Activity有问题的文件,并且我已经尝试调用InputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0). 两种方法都不起作用;如果键盘由另一个应用程序打开,并且我还没有具有焦点的视图,则InputMethodManager拒绝我关闭键盘的尝试,大概是为了防止我控制另一个应用程序拥有的键盘的可见性。

有没有办法在启动您自己的应用程序时立即关闭来自另一个应用程序的挥之不去Activity的键盘,这样键盘在您的第一个布局发生时就消失了?stateHidden在我看来,不为您执行此操作的事实是一个错误。

标签: android

解决方案


键盘仍然处于启动状态的事实是一个错误。但是据我所知,没有办法以编程方式解决这个问题。问题是键盘在连接的基础上工作,并且连接是与以前的应用程序。因此,在您建立联系之前,无法与它交谈。

您提到的 size hack 确实应该避免,因为它远未达到 100%。还有其他一些事情会破坏它,例如分屏,画中画模式,并且很可能是新的可折叠手机。还可以将其连接到任何显示器。只有那些不了解并且不测试他们的代码的人才会“常见”做法。基本上是那些四处飘荡的破碎代码之一,因为它有点工作,人们不会看得更深。

您可以强制将焦点设置到窗口中接受文本输入的视图。那将强制建立联系。但是在关闭它时你会出现卡顿,并且在这不是问题的情况下会发生。

最后,解决方案是编写您的应用程序,使其不关心键盘状态,并且在键盘打开/关闭时不尝试更改应用程序的行为或外观,操作系统不适合它。

完全同意你的观点,操作系统应该支持这一点。但自 2010 年我写键盘以来,我就一直这么说。它还没有改变,我不希望它......真的。谷歌从未对改进键盘 API 表现出太大兴趣,即使我在世界上最大的 3rd 方键盘应用程序工作时,他们也不想要反馈或投入资源。


推荐阅读