如何以编程方式关闭/隐藏 Android 软键盘?

19,046次阅读
没有评论

共计 2668 个字符,预计需要花费 7 分钟才能阅读完成。

做安卓开发的时候,会有各种各样的想法和疑问,例如:怎么对软键盘关闭或者怎么对软键盘隐藏?震惊

问题

我的布局中有一个 EditText 和一个 Button

在编辑字段中写入并单击 后 Button,我想在触摸键盘外部时隐藏虚拟键盘。我认为这是一段简单的代码,但是在哪里可以找到它的示例?

解决方法

为了澄清这种疯狂行为,我首先代表所有 Android 用户对 Google 对软键盘的彻底荒谬的处理表示歉意。对于同一个简单的问题,之所以有这么多不同的答案,是因为这个 API 和 Android 中的许多其他 API 一样,设计得很糟糕。我想不出有什么礼貌的方式来表达它。

我想隐藏键盘。我期望向 Android 提供以下声明:Keyboard.hide()。结束。非常感谢。但安卓有一个问题。您必须使用 InputMethodManager 来隐藏键盘。好吧,好吧,这是 Android 的键盘 API。但!您需要拥有 Context 才能访问 IMM。现在我们有一个问题。我可能想从没有使用或不需要任何 Context. 或者更糟糕的是,IMM 要求您指定要隐藏键盘的内容 View(或者更糟糕的是,指定要隐藏的内容)。Window

这就是隐藏键盘如此具有挑战性的原因。亲爱的谷歌:当我查找蛋糕的食谱时,RecipeProvider 地球上没有人会拒绝向我提供食谱,除非我首先回答谁会吃蛋糕以及在哪里吃蛋糕!

这个悲伤的故事以丑陋的事实结束:要隐藏 Android 键盘,您将需要提供 2 种形式的标识:aContext 以及 aView 或 a Window。

我创建了一个静态实用方法,只要您从 Activity.

public static void hideKeyboard(Activity activity) {InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    // 找到当前聚焦的视图,这样我们就可以从中获取正确的窗口令牌。View view = activity.getCurrentFocus();
    // 如果当前没有视图具有焦点,则创建一个新视图,这样我们就可以从中获取窗口令牌
    if (view == null) {view = new View(activity);
    }
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

请注意,此实用方法仅在从 Activity! 调用时才有效。上述方法调用 getCurrentFocus 目标 Activity 来获取正确的窗口令牌。

EditText 但是假设您想对托管在 a 中的主机隐藏键盘 DialogFragment?您不能使用上面的方法:

hideKeyboard(getActivity()); // 行不通 

这是行不通的,因为您将传递对 Fragment 的 host 的引用 Activity,而显示 时主机将没有焦点控制 Fragment!哇!因此,为了隐藏片段中的键盘,我采用了较低级别、更常见且更丑陋的方法:

public static void hideKeyboardFrom(Context context, View view) {InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

以下是从浪费更多时间来追求此解决方案中收集到的一些附加信息:

关于 windowSoftInputMode

还有一个争论点需要注意。默认情况下,Android 会自动将初始焦点分配 EditText 给 Activity. 很自然地,InputMethod(通常是软键盘)将通过显示自身来响应焦点事件。windowSoftInputMode 当中的属性设置 AndroidManifest.xml 为 时 stateAlwaysHidden,指示键盘忽略此自动分配的初始焦点。

几乎令人难以置信的是,当您触摸控件时,它似乎没有采取任何措施阻止键盘打开(除非 focusable=”false” 和 / 或 focusableInTouchMode=”false” 被分配给控件)。显然,windowSoftInputMode 设置仅适用于自动焦点事件,不适用于触摸事件触发的焦点事件。

因此,stateAlwaysHidden 这个名字确实很糟糕。也许应该改为调用它 ignoreInitialFocus。


更新:获取窗口令牌的更多方法

如果没有聚焦视图(例如,如果您刚刚更改了片段,则可能会发生),还有其他视图将提供有用的窗口令牌。

这些是上述代码的替代方案,if (view == null)   view = new View(activity); 它们没有明确引用您的活动。

在片段类中:

view = getView().getRootView().getWindowToken();

给定一个片段 fragment 作为参数:

view = fragment.getView().getRootView().getWindowToken();

从您的内容主体开始:

view = findViewById(android.R.id.content).getRootView().getWindowToken();

更新 2:清除焦点以避免在从后台打开应用程序时再次显示键盘

将此行添加到方法的末尾:

view.clearFocus();

文章来源地址 https://www.toymoban.com/diary/problem/423.html

到此这篇关于如何以编程方式关闭 / 隐藏 Android 软键盘?的文章就介绍到这了, 更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持 TOY 模板网!

原文地址:https://www.toymoban.com/diary/problem/423.html

如若转载,请注明出处:如若内容造成侵权 / 违法违规 / 事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于1970-01-01发表,共计2668字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)