windows关闭软键盘 - 关闭/隐藏Android软键盘
hidesoftinputfromwindow无效 (20)
简短的回答
在OnClick
侦听onEditorAction
中,使用IME_ACTION_DONE
调用EditText
的IME_ACTION_DONE
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
someEditText.onEditorAction(EditorInfo.IME_ACTION_DONE)
}
});
深入研究
我觉得这种方法更好,更简单,更符合Android的设计模式。 在上面的简单示例中(通常在大多数常见情况下),您将拥有一个具有焦点的EditText
,它通常也是首先调用键盘的键盘(它肯定能够调用它)许多常见情况)。 以同样的方式, 它应该是释放键盘的那个,通常可以通过ImeAction
来完成。 只要看看带有android:imeOptions="actionDone"
的EditText
如何表现,你想用同样的方法实现相同的行为。
检查这个相关的答案
我的布局中有一个EditText
和一个Button
。
在编辑字段中写入并单击Button
,我想隐藏虚拟键盘。 我假设这是一段简单的代码,但我在哪里可以找到它的一个例子?
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);
}
}
为了帮助澄清这种疯狂,我想首先代表所有Android用户道歉,谷歌对软键盘的彻头彻尾的荒谬处理。 对于同样简单的问题,有很多答案,每个不同的原因是因为这个API与Android中的许多其他答案一样,设计非常糟糕。 我可以想到没有礼貌的方式陈述它。
我想隐藏键盘。 我期望为Android提供以下声明: Keyboard.hide()
。 结束。 非常感谢你。 但Android存在问题。 您必须使用InputMethodManager
来隐藏键盘。 好的,很好,这是Android的键盘API。 但! 您需要具有Context
才能访问IMM。 现在我们遇到了问题。 我可能想要从没有任何使用或不需要任何Context
的静态或实用程序类中隐藏键盘。 或者更糟糕的是,IMM要求您指定要隐藏键盘FROM的View
(甚至更糟糕的是什么Window
)。
这使得隐藏键盘变得如此具有挑战性。 亲爱的谷歌:当我查找蛋糕的配方时,地球上没有RecipeProvider
拒绝向我提供配方,除非我第一次回答世界卫生组织,蛋糕将被吃掉,哪里会被吃掉!
这个悲伤的故事以丑陋的事实告终:要隐藏Android键盘,您需要提供两种形式的识别: Context
以及View
或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
调用时才有效! 上面的方法调用目标Activity
getCurrentFocus
来获取正确的窗口标记。
但是假设您想要从DialogFragment
托管的EditText
隐藏键盘? 你不能使用上面的方法:
hideKeyboard(getActivity()); //won't work
这将无效,因为您将传递对Fragment
的主机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会自动将初始焦点分配给Activity
的第一个EditText
或focusable控件。 由此可见,InputMethod(通常是软键盘)将通过显示自身来响应焦点事件。 AndroidManifest.xml
的windowSoftInputMode
属性设置为stateAlwaysHidden
,指示键盘忽略此自动分配的初始焦点。
<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
几乎令人难以置信的是,当您触摸控件时,似乎无法阻止键盘打开(除非将focusable="false"
和/或focusableInTouchMode="false"
分配给控件)。 显然,windowSoftInputMode设置仅适用于自动焦点事件,而不适用于触发触摸事件触发的事件。
因此, stateAlwaysHidden
名字确实非常糟糕。 它也许应该被称为ignoreInitialFocus
。
希望这可以帮助。
更新:获取窗口令牌的更多方法
如果没有焦点视图(例如,如果你刚刚更改了片段就会发生),还有其他视图将提供有用的窗口令牌。
if (view == null) view = new View(activity);
这些是上述代码的替代品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();
从搜索到这里,我找到了一个适合我的答案
// Show soft-keyboard:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
// Hide soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
到目前为止, Saurabh Pareek有最好的答案。
不过,不妨使用正确的旗帜。
/* 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);
实际使用的例子
/* 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 ... */
}
只需在您的活动中使用此优化代码:
if (this.getCurrentFocus() != null) {
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
如果这里的所有其他答案对您不起作用,那么还有另一种手动控制键盘的方法。
用它来创建一个函数来管理一些EditText
的属性:
public void setEditTextFocus(boolean isFocused) {
searchEditText.setCursorVisible(isFocused);
searchEditText.setFocusable(isFocused);
searchEditText.setFocusableInTouchMode(isFocused);
if (isFocused) {
searchEditText.requestFocus();
}
}
然后,确保您打开/关闭键盘的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);
}
}
}
});
现在,每当你想手动打开键盘时调用:
setEditTextFocus(true);
关闭电话:
setEditTextFocus(false);
您可以使用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);
}
这将强制键盘在所有情况下都被隐藏。 在某些情况下,您需要传入InputMethodManager.HIDE_IMPLICIT_ONLY
作为第二个参数,以确保在用户未明确强制显示键盘时(仅通过按住菜单)隐藏键盘。
注意:如果要在Kotlin中执行此操作,请使用: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
我正在使用自定义键盘输入十六进制数字,因此我无法显示IMM键盘...
在v3.2.4_r1中添加了setSoftInputShownOnFocus(boolean show)
以控制天气或不显示TextView获得焦点时的键盘,但它仍然隐藏,因此必须使用反射:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
try {
Method method = TextView.class.getMethod("setSoftInputShownOnFocus", boolean.class);
method.invoke(mEditText, false);
} catch (Exception e) {
// Fallback to the second method
}
}
对于旧版本,我使用OnGlobalLayoutListener
获得了非常好的结果(但远非完美),在我的根视图中借助OnGlobalLayoutListener
添加,然后检查键盘是否显示如下:
@Override
public void onGlobalLayout() {
Configuration config = getResources().getConfiguration();
// Dont allow the default keyboard to show up
if (config.keyboardHidden != Configuration.KEYBOARDHIDDEN_YES) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mRootView.getWindowToken(), 0);
}
}
最后一个解决方案可以显示键盘一瞬间,并与选择手柄混淆。
当键盘进入全屏时,不会调用onGlobalLayout。 为避免这种情况,请使用TextView#setImeOptions(int)或TextView XML声明:
android:imeOptions="actionNone|actionUnspecified|flagNoFullscreen|flagNoExtractUi"
更新:刚刚找到哪些对话框用于永不显示键盘并适用于所有版本:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
我花了两天多的时间来处理帖子中发布的所有解决方案,并发现它们缺乏这种或那种方式。 我的确切要求是有一个100%可靠性的按钮显示或隐藏屏幕键盘。 当键盘处于隐藏状态时,无论用户点击什么输入字段,都不应重新出现。 当它处于可见状态时,无论用户点击什么按钮,键盘都不会消失。 这需要在Android 2.2+上运行,直到最新的设备。
你可以在我的app clean RPN中看到这个的有效实现。
在许多不同的手机(包括froyo和姜饼设备)上测试了许多建议的答案后,很明显Android应用程序可以可靠地:
- 暂时隐藏键盘。 当用户聚焦新文本字段时,它将再次重新出现。
- 在活动开始时显示键盘,并在活动上设置一个标志,指示键盘应始终可见。 只有在活动初始化时才能设置此标志。
- 将活动标记为从不显示或允许使用键盘。 只有在活动初始化时才能设置此标志。
对我来说,暂时隐藏键盘是不够的。 在某些设备上,只要新的文本字段被聚焦,它就会重新出现。 由于我的应用程序在一个页面上使用多个文本字段,因此聚焦新文本字段将导致隐藏键盘再次弹回。
不幸的是,列表中的第2项和第3项仅在启动活动时才具有可靠性。 活动变得可见后,您无法永久隐藏或显示键盘。 诀窍是当用户按下键盘切换按钮时实际重启您的活动。 在我的应用程序中,当用户按下切换键盘按钮时,运行以下代码:
private void toggleKeyboard(){
if(keypadPager.getVisibility() == View.VISIBLE){
Intent i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
Bundle state = new Bundle();
onSaveInstanceState(state);
state.putBoolean(SHOW_KEYBOARD, true);
i.putExtras(state);
startActivity(i);
}
else{
Intent i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
Bundle state = new Bundle();
onSaveInstanceState(state);
state.putBoolean(SHOW_KEYBOARD, false);
i.putExtras(state);
startActivity(i);
}
}
这会导致当前活动将其状态保存到Bundle中,然后启动活动,通过布尔值来指示是否应显示或隐藏键盘。
在onCreate方法中,运行以下代码:
if(bundle.getBoolean(SHOW_KEYBOARD)){
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(newEquationText,0);
getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
else{
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
如果应该显示软键盘,则告诉InputMethodManager显示键盘,并指示窗口使软输入始终可见。 如果应隐藏软键盘,则设置WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM。
这种方法可以在我测试过的所有设备上可靠运行 - 从运行Android 2.2的4岁HTC手机到运行4.2.2的nexus 7。这种方法的唯一缺点是你需要小心处理后退按钮。由于我的应用程序基本上只有一个屏幕(它是一个计算器),我可以覆盖onBackPressed()并返回到设备主屏幕。
用这个
this.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
请在onCreate()
尝试以下代码
EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);
这应该工作:
public class KeyBoard {
public static void show(Activity activity){
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY); // show
}
public static void hide(Activity activity){
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); // hide
}
public static void toggle(Activity activity){
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
if (imm.isActive()){
hide(activity);
} else {
show(activity);
}
}
}
KeyBoard.toggle(activity);
隐藏软键盘也很有用:
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);
这可用于在用户实际触摸editText视图之前抑制软键盘。
在某些情况下,除其他所有方法外,此方法都可以使用 这节省了我的一天:)
public static void hideSoftKeyboard(Activity activity) {
if (activity != null) {
InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
if (activity.getCurrentFocus() != null && inputManager != null) {
inputManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
inputManager.hideSoftInputFromInputMethod(activity.getCurrentFocus().getWindowToken(), 0);
}
}
}
public static void hideSoftKeyboard(View view) {
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputManager != null) {
inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
}
对于我的情况,我在操作栏中使用了SearchView。用户执行搜索后,键盘将再次弹出。
使用InputMethodManager没有关闭键盘。我不得不clearFocus并将搜索视图的焦点设置为false:
mSearchView.clearFocus();
mSearchView.setFocusable(false);
我有这种情况,我的EditText
位置也可以在一个AlertDialog
,所以键盘应该关闭解雇。以下代码似乎在任何地方都可以使用:
public static void hideKeyboard( Activity activity ) {
InputMethodManager imm = (InputMethodManager)activity.getSystemService( Context.INPUT_METHOD_SERVICE );
View f = activity.getCurrentFocus();
if( null != f && null != f.getWindowToken() && EditText.class.isAssignableFrom( f.getClass() ) )
imm.hideSoftInputFromWindow( f.getWindowToken(), 0 );
else
activity.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN );
}
或者到这一切它的解决方案,如果你想关闭软键盘从任何地方,而不必是用于打开键盘(EditText上)字段的引用,但仍然希望这样做,如果该领域的重点,你可以使用这(来自一项活动):
if (getCurrentFocus() != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
简单易用的方法,只需调用hideKeyboardFrom(YourActivity.this); 隐藏键盘
/**
* This method is used to hide keyboard
* @param activity
*/
public static void hideKeyboardFrom(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
protected void hideSoftKeyboard(EditText input) {
input.setInputType(0);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
}