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

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


当前回答

为了帮助澄清这种疯狂,我想首先代表所有Android用户为谷歌对软键盘的荒谬处理道歉。对于同一个简单的问题,有这么多答案,每个答案都不同,原因是这个API和Android中的许多其他API一样,设计得很糟糕。我想不出有礼貌的方式来表达。

我想隐藏键盘。我希望为Android提供以下语句:Keyboard.hide().结束。非常感谢你。但Android有一个问题。必须使用InputMethodManager隐藏键盘。好吧,这是Android的键盘API。但是!您需要有上下文才能访问IMM。现在我们有一个问题。我可能想将键盘隐藏在一个静态类或实用程序类中,该类不使用或不需要任何上下文。或者更糟糕的是,IMM要求您指定要隐藏键盘的视图(甚至更糟糕的,窗口)。

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

这个悲伤的故事以丑陋的事实结尾:要隐藏Android键盘,你需要提供两种形式的标识:上下文和视图或窗口。

我已经创建了一个静态实用程序方法,只要您从“活动”调用它,它就可以非常可靠地完成任务。

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以获取适当的窗口标记。

但是,假设您想对DialogFragment中托管的EditText隐藏键盘?您不能使用上述方法:

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

这不会起作用,因为您将传递一个对Fragment的主机Activity的引用,在显示Fragment时,该主机Activity将没有焦点控制!哇!因此,为了隐藏键盘的碎片,我选择了更低级、更常见、更丑陋的方法:

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或可聚焦控件。很自然,InputMethod(通常是软键盘)将通过显示自己来响应焦点事件。AndroidManifest.xml中的windowSoftInputMode属性设置为stateAlwaysHidden时,指示键盘忽略自动分配的初始焦点。

<activity
    android:name=".MyActivity"
    android:windowSoftInputMode="stateAlwaysHidden"/>

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

因此,stateAlwaysHidden的名称确实非常糟糕。它可能应该被称为ignoreInitialFocus。


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

如果没有聚焦视图(例如,如果您只是更改了片段,可能会发生这种情况),则会有其他视图提供有用的窗口标记。

如果(view==null)view=new view(activity),则这些是上述代码的替代方案;这些并没有明确提到你的活动。

在片段类中:

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

给定片段片段作为参数:

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

从内容主体开始:

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

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

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

view.clearFocus();

其他回答

对于开放式键盘:

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(edtView, InputMethodManager.SHOW_IMPLICIT);

对于关闭/隐藏键盘:

 InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
 imm.hideSoftInputFromWindow(edtView.getWindowToken(), 0);

更新:我不知道为什么这个解决方案不再有效(我刚刚在Android 23上测试过)。请改用Saurabh Pareek的溶液。这里是:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
//Hide:
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
//Show
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

旧答案:

//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

在调用onTouchListener之后:

findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Utils.hideSoftKeyboard(activity);
        return false;
    }
});

这对我有用。。

EditText editText=(EditText)findViewById(R.id.edittext1);

放在onClick()中的代码行下面

editText.setFocusable(false);
editText.setFocusableInTouchMode(true);

这里隐藏键盘,当我们单击按钮时,当我们触摸EditText键盘时,将显示。

(OR)

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

每次都像魔术般

private void closeKeyboard() {
    InputMethodManager inputManager = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

}

private void openKeyboard() {
    InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    if(imm != null){
        imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
    }
}