Android 关闭/隐藏安卓软键盘
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1109022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Close/hide android soft keyboard
提问by Vidar Vestnes
I have an EditText
and a Button
in my layout.
我的布局中有一个EditText
和一个Button
。
After writing in the edit field and clicking on the Button
, I want to hide the virtual keyboard. I assume that this is a simple piece of code, but where can I find an example of it?
在编辑字段中写入并单击 后Button
,我想隐藏虚拟键盘。我认为这是一段简单的代码,但我在哪里可以找到它的示例?
When touching outside the keyboard.
触摸键盘外部时。
采纳答案by rmirabelle
To help clarify this madness, I'd like to begin by apologizing on behalf of all Android users for Google's downright ridiculous treatment of the soft keyboard. The reason there are so many answers, each different, for the same simple question is because this API, like many others in Android, is horribly designed. I can think of no polite way to state it.
为了澄清这种疯狂,我首先代表所有 Android 用户为 Google 对软键盘的荒谬处理道歉。对于同一个简单的问题,有这么多答案,每个答案都不同,是因为这个 API 与 Android 中的许多其他 API 一样,设计得非常糟糕。我想不出礼貌的方式来表达它。
I want to hide the keyboard. I expect to provide Android with the following statement: Keyboard.hide()
. The end. Thank you very much. But Android has a problem. You must use the InputMethodManager
to hide the keyboard. OK, fine, this is Android's API to the keyboard. BUT! You are required to have a Context
in order to get access to the IMM. Now we have a problem. I may want to hide the keyboard from a static or utility class that has no use or need for any Context
. or And FAR worse, the IMM requires that you specify what View
(or even worse, what Window
) you want to hide the keyboard FROM.
我想隐藏键盘。我希望为 Android 提供以下声明:Keyboard.hide()
. 结束。非常感谢。但是安卓有问题。您必须使用InputMethodManager
来隐藏键盘。好的,好的,这是 Android 的键盘 API。但!您必须拥有Context
才能访问 IMM。现在我们有一个问题。我可能想对没有用或不需要任何Context
. 或者更糟糕的是,IMM 要求您指定要隐藏键盘的内容View
(或更糟的是,是什么Window
)。
This is what makes hiding the keyboard so challenging. Dear Google: When I'm looking up the recipe for a cake, there is no RecipeProvider
on Earth that would refuse to provide me with the recipe unless I first answer WHO the cake will be eaten by AND where it will be eaten!!
这就是隐藏键盘如此具有挑战性的原因。亲爱的谷歌:当我查找蛋糕的食谱时,RecipeProvider
地球上没有人会拒绝向我提供食谱,除非我先回答谁会吃蛋糕以及在哪里吃蛋糕!!
This sad story ends with the ugly truth: to hide the Android keyboard, you will be required to provide 2 forms of identification: a Context
and either a View
or a Window
.
这个悲伤的故事以一个丑陋的事实结束:要隐藏 Android 键盘,您将需要提供 2 种身份识别形式:aContext
和 aView
或 a Window
。
I have created a static utility method which can do the job VERY solidly, provided you call it from an Activity
.
我创建了一个静态实用程序方法,它可以非常可靠地完成这项工作,前提是您从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);
}
Be aware that this utility method ONLY works when called from an Activity
! The above method calls getCurrentFocus
of the target Activity
to fetch the proper window token.
请注意,此实用程序方法仅在从Activity
! getCurrentFocus
目标的上述方法调用Activity
以获取正确的窗口令牌。
But suppose you want to hide the keyboard from an EditText
hosted in a DialogFragment
? You can't use the method above for that:
但是假设您想对EditText
托管在DialogFragment
? 您不能为此使用上述方法:
hideKeyboard(getActivity()); //won't work
This won't work because you'll be passing a reference to the Fragment
's host Activity
, which will have no focused control while the Fragment
is shown! Wow! So, for hiding the keyboard from fragments, I resort to the lower-level, more common, and uglier:
这将不起作用,因为您将传递对Fragment
's 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);
}
Below is some additional information gleaned from more time wasted chasing this solution:
以下是从追逐此解决方案所浪费的更多时间中收集的一些附加信息:
About windowSoftInputMode
关于 windowSoftInputMode
There's yet another point of contention to be aware of. By default, Android will automatically assign initial focus to the first EditText
or focusable control in your Activity
. It naturally follows that the InputMethod (typically the soft keyboard) will respond to the focus event by showing itself. The windowSoftInputMode
attribute in AndroidManifest.xml
, when set to stateAlwaysHidden
, instructs the keyboard to ignore this automatically-assigned initial focus.
还有一个争论点需要注意。默认情况下,Android将自动最初的焦点分配给第一个EditText
在你或可聚焦控制Activity
。很自然地,InputMethod(通常是软键盘)将通过显示自己来响应焦点事件。中的windowSoftInputMode
属性AndroidManifest.xml
设置为 时stateAlwaysHidden
,指示键盘忽略此自动分配的初始焦点。
<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
Almost unbelievably, it appears to do nothing to prevent the keyboard from opening when you touch the control (unless focusable="false"
and/or focusableInTouchMode="false"
are assigned to the control). Apparently, the windowSoftInputMode setting applies only to automatic focus events, not to focus events triggered by touch events.
几乎令人难以置信的是,当您触摸控件时,它似乎没有阻止键盘打开(除非focusable="false"
和/或focusableInTouchMode="false"
分配给控件)。显然,windowSoftInputMode 设置仅适用于自动焦点事件,不适用于触摸事件触发的焦点事件。
Therefore, stateAlwaysHidden
is VERY poorly named indeed. It should perhaps be called ignoreInitialFocus
instead.
因此,stateAlwaysHidden
确实是非常糟糕的名字。也许应该ignoreInitialFocus
改为调用它。
Hope this helps.
希望这可以帮助。
UPDATE: More ways to get a window token
更新:获取窗口令牌的更多方法
If there is no focused view (e.g. can happen if you just changed fragments), there are other views that will supply a useful window token.
如果没有聚焦视图(例如,如果您刚刚更改片段可能会发生这种情况),还有其他视图将提供有用的窗口标记。
These are alternatives for the above code if (view == null) view = new View(activity);
These don't refer explicitly to your activity.
这些是上述代码的替代方案,if (view == null) view = new View(activity);
这些并未明确指代您的活动。
Inside a fragment class:
在片段类中:
view = getView().getRootView().getWindowToken();
Given a fragment fragment
as a parameter:
给定一个片段fragment
作为参数:
view = fragment.getView().getRootView().getWindowToken();
Starting from your content body:
从您的内容正文开始:
view = findViewById(android.R.id.content).getRootView().getWindowToken();
UPDATE 2: Clear focus to avoid showing keyboard again if you open the app from the background
更新 2:如果您从后台打开应用程序,请清除焦点以避免再次显示键盘
Add this line to the end of the method:
将此行添加到方法的末尾:
view.clearFocus();
view.clearFocus();
回答by Reto Meier
You can force Android to hide the virtual keyboard using the InputMethodManager, calling hideSoftInputFromWindow
, passing in the token of the window containing your focused view.
您可以使用InputMethodManager强制 Android 隐藏虚拟键盘,调用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);
}
This will force the keyboard to be hidden in all situations. In some cases you will want to pass in InputMethodManager.HIDE_IMPLICIT_ONLY
as the second parameter to ensure you only hide the keyboard when the user didn't explicitly force it to appear (by holding down menu).
这将强制在所有情况下隐藏键盘。在某些情况下,您可能希望InputMethodManager.HIDE_IMPLICIT_ONLY
作为第二个参数传入,以确保仅在用户没有明确强制显示键盘时才隐藏键盘(通过按住菜单)。
Note:If you want to do this in Kotlin, use:
context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
注意:如果您想在 Kotlin 中执行此操作,请使用:
context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
Kotlin Syntax
Kotlin 语法
// Check if no view has focus:
val view = this.currentFocus
view?.let { v ->
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
imm?.hideSoftInputFromWindow(v.windowToken, 0)
}
回答by Garnet Ulrich
Also useful for hiding the soft-keyboard is:
对于隐藏软键盘也很有用:
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);
This can be used to suppress the soft-keyboard until the user actually touches the editText View.
这可用于抑制软键盘,直到用户实际触摸 editText 视图。
回答by Saurabh Pareek
I got one more solution to hide keyboard:
我还有另一种隐藏键盘的解决方案:
InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
Here pass HIDE_IMPLICIT_ONLY
at the position of showFlag
and 0
at the position of hiddenFlag
. It will forcefully close soft Keyboard.
这里通过HIDE_IMPLICIT_ONLY
在 的位置showFlag
和0
的位置hiddenFlag
。它将强行关闭软键盘。
回答by mckoss
Meier's solution works for me too. In my case the top level of my App is a tabHost and I want to hide the keyword when switching tabs - I get the window token from the tabHost View.
Meier 的解决方案也适用于我。在我的情况下,我的应用程序的顶层是 tabHost 并且我想在切换选项卡时隐藏关键字 - 我从 tabHost 视图中获取窗口令牌。
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String tabId) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(tabHost.getApplicationWindowToken(), 0);
}
}
回答by Jeyavel
Please try this below code in onCreate()
请在下面的代码中尝试 onCreate()
EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);
回答by Nguyen Minh Binh
Update:I don't know why this solution is not work any more ( I just tested on Android 23). Please use the solution of Saurabh Pareekinstead. Here it is:
更新:我不知道为什么这个解决方案不再起作用(我刚刚在 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);
Old answer:
旧答案:
//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
回答by Sreedev R
protected void hideSoftKeyboard(EditText input) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
}
回答by Rotemmiz
If all the other answers here don't work for you as you would like them to, there's another way of manually controlling the keyboard.
如果这里的所有其他答案都不如您所愿,那么还有另一种手动控制键盘的方法。
Create a function with that will manage some of the EditText
's properties:
创建一个函数,它将管理 的一些EditText
属性:
public void setEditTextFocus(boolean isFocused) {
searchEditText.setCursorVisible(isFocused);
searchEditText.setFocusable(isFocused);
searchEditText.setFocusableInTouchMode(isFocused);
if (isFocused) {
searchEditText.requestFocus();
}
}
Then, make sure that onFocus of the EditText
you open/close the keyboard:
然后,确保EditText
您打开/关闭键盘的onFocus :
searchEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (v == searchEditText) {
if (hasFocus) {
// Open keyboard
((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(searchEditText, InputMethodManager.SHOW_FORCED);
} else {
// Close keyboard
((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(searchEditText.getWindowToken(), 0);
}
}
}
});
Now, whenever you want to open the keyboard manually call:
现在,每当您想手动打开键盘时,请调用:
setEditTextFocus(true);
And for closing call:
对于闭幕式:
setEditTextFocus(false);
回答by Alex
Saurabh Pareekhas the best answer so far.
到目前为止,Saurabh Pareek 给出了最好的答案。
Might as well use the correct flags, though.
不过,也可以使用正确的标志。
/* hide keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
/* show keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
Example of real use
实际使用示例
/* click button */
public void onClick(View view) {
/* hide keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
/* start loader to check parameters ... */
}
/* loader finished */
public void onLoadFinished(Loader<Object> loader, Object data) {
/* parameters not valid ... */
/* show keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
/* parameters valid ... */
}