关闭/隐藏Android软键盘

我有一个EditTextButton我的布局。

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

答案


您可以强制Android使用InputMethodManager隐藏虚拟键盘,调用hideSoftInputFromWindow,传入含有焦点视图的窗口标记。

// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {  
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

这将迫使键盘在所有情况下隐藏。在某些情况下,您将希望InputMethodManager.HIDE_IMPLICIT_ONLY作为第二个参数传入,以确保在用户没有明确强制显示时隐藏键盘(通过按住菜单)。


为了澄清这种疯狂,我想首先代表所有Android用户道歉,因为谷歌对软键盘的彻底荒谬处理。对于同样简单的问题,有很多答案各不相同,这是因为与Android中的其他许多API一样,这个API的设计非常糟糕。我可以想到没有礼貌的方式来陈述它。

我想隐藏键盘。我期望为Android提供以下声明:Keyboard.hide()。结束。非常感谢你。但Android有一个问题。您必须使用InputMethodManager隐藏键盘。好的,很好,这是Android的键盘API。但!您需要有一个Context以访问IMM。现在我们有一个问题。我可能希望将键盘从静态或实用类中隐藏起来,这些类没有任何用处或者不需要Context。或者更糟糕的是,IMM要求您指定要隐藏键盘FROM的内容View(甚至更糟糕的是Window)。

这就是隐藏键盘如此具有挑战性的原因。亲爱的Google:当我正在查找蛋糕的食谱时,世界上没有人RecipeProvider会拒绝为我提供配方,除非我首先回答世卫组织,蛋糕将被吃掉,并且它将被吃掉!

这个悲伤的故事以丑陋的真相结束:为了隐藏Android键盘,您将需要提供2种形式的识别:a Context和a View或a Window

我已经创建了一个静态实用程序方法,可以非常稳定地完成这项工作,只要您从中调用它Activity

public static void hideKeyboard(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    //Find the currently focused view, so we can grab the correct window token from it.
    View view = activity.getCurrentFocus();
    //If no view currently has focus, create a new one, just so we can grab a window token from it
    if (view == null) {
        view = new View(activity);
    }
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

请注意,这种实用方法只适用于从Activity!上述方法调用getCurrentFocus目标Activity来获取正确的窗口标记。

但是,假设你想隐藏EditText托管在键盘DialogFragment?你不能使用上面的方法:

hideKeyboard(getActivity()); //won't work

这是行不通的,因为你会传递一个对Fragment主人的引用,这个主人ActivityFragment显示时没有集中控制!哇!所以,为了将碎片隐藏起来,我使用了更低级的,更常见的和丑陋的:

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,指示键盘忽略这个自动分配的初始焦点。

<activity
    android:name=".MyActivity"
    android:windowSoftInputMode="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();

添加评论

友情链接:蝴蝶教程