关闭/隐藏Android软键盘
我的布局中有一个EditText
和一个Button
.
在编辑字段中写入并单击后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
第二个参数,以确保仅在用户未明确强制显示键盘时隐藏键盘(通过按住菜单).
注意:如果您想在Kotlin中执行此操作,请使用:
context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
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)
}
- 调用`editText.clearFocus()`然后`InputMethodManager.HIDE_IMPLICIT_ONLY`甚至可以用于`4.1`
- 凉.只是为了澄清一下,如果存在,这只能解除它,但不会*阻止它突然冒出来,对吧?
- 在隐藏softInput之前调用editText.clearFocus()可能会有所帮助
- 谢谢,如果使用0作为第二个参数,这似乎工作得很好.但是,如果我使用InputMethodManager.HIDE_IMPLICIT_ONLY,键盘永远不会被隐藏(虽然我没有按住菜单).任何提示?
- 4.4/htc对我有用的是执行`View focused = getCurrentFocus()`来获取当前焦点视图*调用`focused.clearFocus()`,然后调用`inputMethodManager.hideSoftInputFromWindow(focused.getWindowToken( ),0)`(带有清晰的标志).
- 如果你不确切知道字段拥有焦点,它就不起作用.
- @Roflcoptr - hideImplicitOnly仅在editText获得焦点时键盘自动打开.在您的情况下,您可能正在按下editText,表示您要键入它,这是一个显式操作.
- 当然你需要重新设置它.请验证如何撤消此更改.
- 在Android 4.1上适用于我,但仅限于您使用0而不是HIDE_IMPLICIT_ONLY.此外*它*不会阻止键盘再次弹出.我使用`EditText` +发送按钮,当你运行它时,`EditText`保持焦点,键盘被隐藏.然后当您点击`EditText`时,键盘会再次显示.完善!
- 此方法假定特定的EditText不为null.但是假设您的用户按下设备上的Home按钮,该按钮调用onStop()方法.然后对EditText的任何引用都会抛出NullPointerException.
- 对我不起作用(三星Galaxy Ace 2.3.3,HTC Desire HD 2.3.5)
- 还有什么可以帮助的,就是将这段代码包装成runnable并将postDelayed包装到getCurrentFocus()View中
- now `getSystemService()` requires a `Context` and a serviceClass `Class`. For the context I can call `requiredContext` but what about for the serviceClass?
为了帮助澄清这种疯狂,我想首先代表所有Android用户道歉,谷歌对软键盘的彻头彻尾的荒谬处理.对于同样简单的问题,有这么多答案的原因有很多,因为这个API与Android中的许多其他API一样,设计非常糟糕.我可以想到没有礼貌的方式陈述它.
我想隐藏键盘.我期望为Android提供以下声明:Keyboard.hide()
.结束.非常感谢你.但Android存在问题.您必须使用InputMethodManager
隐藏键盘.好的,很好,这是Android的键盘API.但!您需要拥有一个Context
才能访问IMM.现在我们遇到了问题.我可能想要将键盘隐藏在没有任何用途或需要的静态或实用程序类中Context
.或者更糟糕的是,IMM要求您指定要隐藏键盘FROM的内容View
(甚至更糟Window
).
这使得隐藏键盘变得如此具有挑战性.亲爱的谷歌:当我正在寻找蛋糕RecipeProvider
的食谱时,除非我第一次回答世界卫生组织,否则地球上没有人拒绝向我提供食谱,蛋糕将被吃掉,它会被吃掉!
这个悲伤的故事以丑陋的事实结束:要隐藏Android键盘,您需要提供两种形式的识别: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
主机的引用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
,指示键盘忽略这个自动分配的初始焦点.
<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();
- Google应该只真正提供`Keyboard.hide();`实用工具
- @rmirabelle在`Fragment`中,似乎可以使用`getActivity().getWindow().getDecorView()`
隐藏软键盘也很有用:
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);
这可用于在用户实际触摸editText视图之前抑制软键盘.
- 您还可以通过在清单中的活动中添加android:windowSoftInputMode ="stateHidden"来实现相同的效果.
- 在API级别9上的片段(引用拥有活动)中尝试了这一点,但遗憾的是它无法正常工作.尝试在onResume和onActivityCreated中调用它 - 没有效果.
- 当焦点仍在EditText中时(例如,在触摸按钮后),这不起作用.使用Reto的解决方案.
- 为什么重写清单设置是个坏主意?我是从片段中调用它的.没有适用于片段的清单设置......
- 我正在进行对话,这很有效.我正在使用Android 3.2.我把它放在onCreateDialog(Bundle)方法中.它在onCreate方法中不起作用.Dialog dialog = super.onCreateDialog(savedInstanceState); dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 结果是我的EditTexts视图显示没有键盘.当用户触摸编辑文本时,键盘会显示.
- 这是一个坏主意,因为它会覆盖AndroidManifest设置.
我还有一个隐藏键盘的解决方案:
InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
在这里通过HIDE_IMPLICIT_ONLY
位置showFlag
和0
位置hiddenFlag
.它会强行关闭软键盘.
- @Mark:因为该方法被称为"toggleSoftInput",而不是"hideSoftInput":)
- 为什么这会显示键盘,如果它被隐藏?:)
- 此解决方案显示隐藏的键盘.这是不正确的
- 你在showflags参数中使用了hide标志.这只能起作用,因为常量使用相同的整数.[使用正确标志的示例](http://stackoverflow.com/a/15587937/197359)
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);
}
}
请尝试以下代码 onCreate()
EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);
- 这是合法的Javadoc(不是黑客)虽然我会将该方法重写为`editView.setInputType(InputType.TYPE_NULL);`
- 如http://code.google.com/p/android/issues/detail?id=7115中所述,此方法可以解决2.0和2.1中"无法隐藏软键盘"错误的问题.上面列出的hideSoftInputFromWindow方法在我尝试时没有用,但editView.setInputType(0)做了.
- 但这有用,它隐藏了android:提示.我正在使用Android 1.5
更新:
我不知道为什么这个解决方案不再起作用(我刚刚在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);
- 我应该在哪里放置此代码?我试图粘贴getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 在onCreate()但键盘永远不会被隐藏
protected void hideSoftKeyboard(EditText input) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
}
- 这对我有用!但为什么你把**input.setInputType(0)**?当我有那行代码时,我无法与_EditTextView_交互(当我删除它时它工作).
如果这里的所有其他答案对您不起作用,那么还有另一种手动控制键盘的方法.
用它创建一个函数来管理一些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);
到目前为止,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 ... */
}
- 不.在我的三星标签,Android 5.0上,上面所谓的"隐藏键盘"代码将切换软键盘 - 如果已经隐藏,它将显示它.这个函数在名称中有TOGGLE是有原因的.
- @Mazen:使用`fragment.getActivity().getSystemService();`
从搜索到这里,我找到了一个适合我的答案
// 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);
简短的回答
在你的OnClick
听众拨打onEditorAction
的EditText
用IME_ACTION_DONE
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
someEditText.onEditorAction(EditorInfo.IME_ACTION_DONE)
}
});
深入研究
我觉得这种方法更好,更简单,更符合Android的设计模式.在上面的简单示例中(通常在大多数常见情况下),您将拥有一个EditText
具有焦点的焦点,并且通常也是首先调用键盘的一个(它肯定能够在很多情况下调用它)常见情景).以同样的方式,它应该是释放键盘的那个,通常可以通过一个ImeAction
.刚看到一个EditText
用android:imeOptions="actionDone"
的行为,要实现以同样的方式相同的行为.
检查这个相关的答案
这应该工作:
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);
我正在使用自定义键盘输入十六进制数字,因此我无法显示IMM键盘...
在v3.2.4 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
}
}
对于旧版本,我得到了非常好的结果(但远非完美)a OnGlobalLayoutListener
,ViewTreeObserver
在我的根视图的帮助下添加,然后检查键盘是否显示如下:
@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);
public void setKeyboardVisibility(boolean show) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if(show){
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}else{
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
}
}
我花了两天多的时间来完成线程中发布的所有解决方案,并发现它们缺乏这种或那种方式.我的确切要求是有一个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()并返回到设备主屏幕.
Alternatively to this all around solution, if you wanted to close the soft keyboard from anywhere without having a reference to the (EditText) field that was used to open the keyboard, but still wanted to do it if the field was focused, you could use this (from an Activity):
if (getCurrentFocus() != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
感谢这个SO答案,我推导出以下内容,在我的情况下,滚动浏览ViewPager的片段时效果很好...
private void hideKeyboard() {
// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
private void showKeyboard() {
// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
}
上面的答案适用于不同的场景但是 如果你想在视图中隐藏键盘并努力获得正确的上下文,请尝试以下方法:
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
hideSoftKeyBoardOnTabClicked(v);
}
}
private void hideSoftKeyBoardOnTabClicked(View v) {
if (v != null && context != null) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
并从构造函数获取上下文:)
public View/RelativeLayout/so and so (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
init();
}
如果要在单元或功能测试期间关闭软键盘,可以通过单击测试中的"后退按钮"来执行此操作:
// Close the soft keyboard from a Test
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
我把"后退按钮"放在引号中,因为上面没有触发有onBackPressed()
问题的Activity.它只是关闭键盘.
确保在继续之前暂停一段时间,因为关闭后退按钮需要一些时间,因此后续点击视图等,直到短暂停顿后才会注册(1秒足够长时间) ).
这对我来说非常适合所有奇怪的键盘行为
private boolean isKeyboardVisible() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
mRootView.getWindowVisibleDisplayFrame(r);
int heightDiff = mRootView.getRootView().getHeight() - (r.bottom - r.top);
return heightDiff > 100; // if more than 100 pixels, its probably a keyboard...
}
protected void showKeyboard() {
if (isKeyboardVisible())
return;
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (getCurrentFocus() == null) {
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
} else {
View view = getCurrentFocus();
inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_FORCED);
}
}
protected void hideKeyboard() {
if (!isKeyboardVisible())
return;
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
View view = getCurrentFocus();
if (view == null) {
if (inputMethodManager.isAcceptingText())
inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);
} else {
if (view instanceof EditText)
((EditText) view).setText(((EditText) view).getText().toString()); // reset edit text bug on some keyboards bug
inputMethodManager.hideSoftInputFromInputMethod(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
以下是你在Mono for Android(AKA MonoDroid)中的表现
InputMethodManager imm = GetSystemService (Context.InputMethodService) as InputMethodManager;
if (imm != null)
imm.HideSoftInputFromWindow (searchbox.WindowToken , 0);
添加到您android:windowSoftInputMode="stateHidden"
在Manifest文件中的活动 .例:
<activity
android:name=".ui.activity.MainActivity"
android:label="@string/mainactivity"
android:windowSoftInputMode="stateHidden"/>
只需在您的活动中使用此优化代码:
if (this.getCurrentFocus() != null) {
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
简单易用的方法,只需调用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);
}
•Kotlin Version
通过Extension Function
使用 kotlin 扩展功能,显示和隐藏软键盘将是如此简单。
扩展函数.kt
import android.app.Activity
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.fragment.app.Fragment
fun Activity.hideKeyboard(): Boolean {
return (getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
.hideSoftInputFromWindow((currentFocus ?: View(this)).windowToken, 0)
}
fun Fragment.hideKeyboard(): Boolean {
return (context?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
.hideSoftInputFromWindow((activity?.currentFocus ?: View(context)).windowToken, 0)
}
fun EditText.hideKeyboard(): Boolean {
return (context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
.hideSoftInputFromWindow(windowToken, 0)
}
fun EditText.showKeyboard(): Boolean {
return (context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
.showSoftInput(this, 0)
}
• 用法
现在在您的Activity
or 中Fragment
,hideKeyboard()
显然可以访问以及从EditText
类似的实例调用它:
editText.hideKeyboard()
对于我的情况,我在操作栏中使用了SearchView.用户执行搜索后,键盘将再次弹出.
使用InputMethodManager没有关闭键盘.我不得不clearFocus并将搜索视图的焦点设置为false:
mSearchView.clearFocus();
mSearchView.setFocusable(false);
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;
}
});
用这个
this.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
我有这种情况,我的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 );
}
我几乎尝试了所有这些答案,我有一些随机问题,尤其是三星Galaxy s5.
我最终得到的是强迫节目和隐藏,它完美地运作:
/**
* Force show softKeyboard.
*/
public static void forceShow(@NonNull Context context) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
/**
* Force hide softKeyboard.
*/
public static void forceHide(@NonNull Activity activity, @NonNull EditText editText) {
if (activity.getCurrentFocus() == null || !(activity.getCurrentFocus() instanceof EditText)) {
editText.requestFocus();
}
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
在某些情况下,除了所有其他方法外,此方法可以起作 这节省了我的一天:)
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);
}
}
}
对于打开键盘:
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);
每次都像魔术般的工作
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);
}
}
感谢上帝,它在 11 年后得到官方支持
首先implementation 'androidx.core:core-ktx:1.6.0-beta01'
给app gradle添加依赖
fun View.showKbd() {
(this.context as? Activity)?.let {
it.showKbd()
}
}
fun View.hideKbd() {
(this.context as? Activity)?.let {
it.hideKbd()
}
}
fun Fragment.showKbd() {
activity?.let {
it.showKbd()
}
}
fun Fragment.hideKbd() {
activity?.let {
it.hideKbd()
}
}
fun Context.showKbd() {
(this as? Activity)?.let {
it.showKbd()
}
}
fun Context.hideKbd() {
(this as? Activity)?.let {
it.hideKbd()
}
}
fun Activity.showKbd(){
WindowInsetsControllerCompat(window, window.decorView).show(WindowInsetsCompat.Type.ime())
}
fun Activity.hideKbd(){
WindowInsetsControllerCompat(window, window.decorView).hide(WindowInsetsCompat.Type.ime())
}
有时你想要的只是输入按钮来折叠keyboard
给EditText
你具有属性的框
android:imeOptions="actionDone"
这会将Enter按钮更改为关闭键盘的Done按钮.
您还可以在EditText上使用setImeOption.
我只是有一个非常类似的情况,我的布局包含EditText和搜索按钮.当我发现我可以在我的editText上将ime选项设置为"actionSearch"时,我意识到我甚至不再需要搜索按钮了.软键盘(在此模式下)有一个搜索图标,可用于启动搜索(键盘会按照您的预期自行关闭).
只需调用下面的方法,它就会隐藏你的键盘,如果它显示出来。
public void hideKeyboard() {
try {
InputMethodManager inputmanager = (InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputmanager != null) {
inputmanager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
}
} catch (Exception var2) {
}
}
这个对我有用..
EditText editText=(EditText)findViewById(R.id.edittext1);
在onClick()下面的代码行
editText.setFocusable(false);
editText.setFocusableInTouchMode(true);
当我们点击按钮时隐藏键盘,当我们触摸EditText键盘时将显示.
(要么)
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
有时您可以拥有一个包含listview的活动,其中包含editText的行,因此您必须在清单中进行设置,SOFT_INPUT_ADJUST_PAN
然后键盘会显示出令人讨厌的内容.
如果你把它放在最后,下面的workarround工作 onCreate
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
}
},100);
试试这个
- 很简单,你可以打电话给你
Activity
public static void hideKeyboardwithoutPopulate(Activity activity) {
InputMethodManager inputMethodManager =
(InputMethodManager) activity.getSystemService(
Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(
activity.getCurrentFocus().getWindowToken(), 0);
}
- 在你的
MainActivitiy
电话中
hideKeyboardwithoutPopulate(MainActivity.this);
这是工作..
只需在函数中传递当前活动实例即可
public void isKeyBoardShow(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
if (imm.isActive()) {
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); // hide
} else {
imm.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY); // show
}
}
现在,差不多 12 年后,我们终于有了一种官方的、向后兼容的方式来使用AndroidX Core 1.5+来做到这一点:
fun View.hideKeyboard() = ViewCompat.getWindowInsetsController(this)
?.hide(WindowInsetsCompat.Type.ime())
或专门用于 Fragment:
fun Fragment.hideKeyboard() = ViewCompat.getWindowInsetsController(requireView())
?.hide(WindowInsetsCompat.Type.ime())
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager)activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
- 这个答案很危险,因为代码可以抛出NullPointerException.`activity.getCurrentFocus()`可以返回null.
在 AndroidManifest.xml
根据<activity..>
集android:windowSoftInputMode="stateAlwaysHidden"
如果要使用Java代码隐藏键盘,请使用以下命令:
InputMethodManager imm = (InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(fEmail.getWindowToken(), 0);
或者,如果您想要始终隐藏键盘,请在AndroidManifest中使用它:
<activity
android:name=".activities.MyActivity"
android:configChanges="keyboardHidden" />
如果有兴趣的话,我已经为Kotlin写了一个小小的扩展名,并没有对它进行过多次测试:
fun Fragment.hideKeyboard(context: Context = App.instance) {
val windowToken = view?.rootView?.windowToken
windowToken?.let {
val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(windowToken, 0)
}
}
App.instance是存储在Application中的静态"this"Application对象
更新:在某些情况下,windowToken为null.我添加了使用反射关闭键盘的其他方法来检测键盘是否关闭
/**
* If no window token is found, keyboard is checked using reflection to know if keyboard visibility toggle is needed
*
* @param useReflection - whether to use reflection in case of no window token or not
*/
fun Fragment.hideKeyboard(context: Context = MainApp.instance, useReflection: Boolean = true) {
val windowToken = view?.rootView?.windowToken
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
windowToken?.let {
imm.hideSoftInputFromWindow(windowToken, 0)
} ?: run {
if (useReflection) {
try {
if (getKeyboardHeight(imm) > 0) {
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS)
}
} catch (exception: Exception) {
Timber.e(exception)
}
}
}
}
fun getKeyboardHeight(imm: InputMethodManager): Int = InputMethodManager::class.java.getMethod("getInputMethodWindowVisibleHeight").invoke(imm) as Int
如果您使用 Kotlin 开发您的应用程序,这真的很容易做到。
添加此扩展功能:
对于活动:
fun Activity.hideKeyboard() {
val inputManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
val view = currentFocus
if (view != null) {
inputManager.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
}
对于片段:
fun Fragment.hideKeyboard() {
activity?.let {
val inputManager = it.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
val view = it.currentFocus
if (view != null) {
inputManager.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
}
}
现在您可以在 Fragment 或 Activity 中简单调用:
hideKeyboard()
对于 kotlin 爱好者。我创建了两个扩展函数。对于 hideKeyboard 的乐趣,您可以将 edittext 的实例作为视图传递。
fun Context.hideKeyboard(view: View) {
(getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.apply {
hideSoftInputFromWindow(view.windowToken, 0)
}
}
fun Context.showKeyboard() {
(getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.apply {
toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
}
}
使用 AndroidX,我们将获得一种显示/隐藏键盘的惊人方式。阅读发行说明 - 1.5.0-alpha02。现在如何隐藏/显示键盘
val controller = view.windowInsetsController
// Show the keyboard
controller.show(Type.ime())
// Hide the keyboard
controller.hide(Type.ime())
链接我自己的答案如何检查 Android 中软件键盘的可见性?和一个惊人的博客,其中包含更多这种变化(甚至更多)。
简单的代码:在onCreate()中使用此代码
实际上,Android权限始终在提供新的更新,但它们并没有解决所有Android开发人员在开发中面临的旧缺陷,默认情况下应由Android权限来处理,从EditText更改焦点时应隐藏/显示软输入键盘选项。但是对此感到抱歉,他们没有进行管理。好的,离开它。
以下是在“活动”或“片段”中显示/隐藏/切换键盘选项的解决方案。
显示视图键盘:
/**
* open soft keyboard.
*
* @param context
* @param view
*/
public static void showKeyBoard(Context context, View view) {
try {
InputMethodManager keyboard = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.showSoftInput(view, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
显示带有活动上下文的键盘:
/**
* open soft keyboard.
*
* @param mActivity context
*/
public static void showKeyBoard(Activity mActivity) {
try {
View view = mActivity.getCurrentFocus();
if (view != null) {
InputMethodManager keyboard = (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.showSoftInputFromInputMethod(view.getWindowToken(), InputMethodManager.SHOW_FORCED);
}
} catch (Exception e) {
e.printStackTrace();
}
}
显示带有Fragment上下文的键盘:
/**
* open soft keyboard.
*
* @param mFragment context
*/
public static void showKeyBoard(Fragment mFragment) {
try {
if (mFragment == null || mFragment.getActivity() == null) {
return;
}
View view = mFragment.getActivity().getCurrentFocus();
if (view != null) {
InputMethodManager keyboard = (InputMethodManager) mFragment.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.showSoftInputFromInputMethod(view.getWindowToken(), InputMethodManager.SHOW_FORCED);
}
} catch (Exception e) {
e.printStackTrace();
}
}
隐藏视图键盘:
/**
* close soft keyboard.
*
* @param context
* @param view
*/
public static void hideKeyBoard(Context context, View view) {
try {
InputMethodManager keyboard = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.hideSoftInputFromWindow(view.getWindowToken(), 0);
} catch (Exception e) {
e.printStackTrace();
}
}
隐藏带有活动上下文的键盘:
/**
* close opened soft keyboard.
*
* @param mActivity context
*/
public static void hideSoftKeyboard(Activity mActivity) {
try {
View view = mActivity.getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
} catch (Exception e) {
e.printStackTrace();
}
}
隐藏带有Fragment上下文的键盘:
/**
* close opened soft keyboard.
*
* @param mFragment context
*/
public static void hideSoftKeyboard(Fragment mFragment) {
try {
if (mFragment == null || mFragment.getActivity() == null) {
return;
}
View view = mFragment.getActivity().getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) mFragment.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
} catch (Exception e) {
e.printStackTrace();
}
}
切换键盘:
/**
* toggle soft keyboard.
*
* @param context
*/
public static void toggleSoftKeyboard(Context context) {
try {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
在科特林
fun hideKeyboard(activity: BaseActivity) {
val view = activity.currentFocus?: View(activity)
val imm = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
这里有隐藏和显示方法。
科特林
fun hideKeyboard(activity: Activity) {
val v = activity.currentFocus
val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(v != null)
imm.hideSoftInputFromWindow(v!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
private fun showKeyboard(activity: Activity) {
val v = activity.currentFocus
val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(v != null)
imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT)
}
爪哇
public static void hideKeyboard(Activity activity) {
View v = activity.getCurrentFocus();
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null && v != null;
imm.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
private static void showKeyboard(Activity activity) {
View v = activity.getCurrentFocus();
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null && v != null;
imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);
}
调用该方法隐藏软键盘
public void hideKeyBoard() {
View view1 = this.getCurrentFocus();
if(view!= null){
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view1.getWindowToken(), 0);
}
}
只需在特定活动的 AndroidManifest 中添加以下行。
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan"/>
片段中的 KOTLIN 解决方案:
fun hideSoftKeyboard() {
val view = activity?.currentFocus
view?.let { v ->
val imm =
activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager // or context
imm.hideSoftInputFromWindow(v.windowToken, 0)
}
}
检查您的清单没有与您的活动相关联的此参数:
android:windowSoftInputMode="stateAlwaysHidden"