程序地带

Android 如何隐藏虚拟键盘?


How do you close/hide the Android soft keyboard using Java?

From:https://stackoverflow.com/questions/1109022/how-do-you-close-hide-the-android-soft-keyboard-using-java


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 that this API, like many others in Android, is horribly designed. I can think of no polite way to state it.


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 InputMethodManagerto hide the keyboard. OK, fine, this is Android’s API to the keyboard. BUT! You are required to have a Contextin 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.


This is what makes hiding the keyboard so challenging. Dear Google: When I’m looking up the recipe for a cake, there is no RecipeProvideron 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!!


This sad story ends with the ugly truth: to hide the Android keyboard, you will be required to provide 2 forms of identification: a Contextand either a Viewor a Window.


I have created a static utility method that can do the job VERY solidly, provided you call it from an 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 getCurrentFocusof the target Activityto fetch the proper window token.


But suppose you want to hide the keyboard from an EditTexthosted in a DialogFragment? You can’t use the method above for that:


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:


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


There’s yet another point of contention to be aware of. By default, Android will automatically assign initial focus to the first EditTextor 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 windowSoftInputModeattribute in AndroidManifest.xml, when set to stateAlwaysHidden, instructs the keyboard to ignore this automatically-assigned initial focus.


<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.


Therefore, stateAlwaysHiddenis VERY poorly named indeed. It should perhaps be called ignoreInitialFocusinstead.


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.


Inside a fragment class:


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

Given a fragment fragmentas a parameter:


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


Add this line to the end of the method:


view.clearFocus();

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Blue3Red1/article/details/112760947

随机推荐

Docker镜像的制作(做笔记)

Dockerfile什么是DockerfileDockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。Dockerfile的作用安装dockerf...

测试小黑 阅读(979)

376. 摆动序列

376.摆动序列如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序...

小桥落花流水 阅读(507)

如何理解卷积神经网络中的通道

卷积神经网络中的通道理解:CNN中的通道介绍可以详细参考如下网址(小白级教程):https://blog.csdn.net/sscc_learn...

A1941314856 阅读(697)

李南江的前端课程知识点(十)补充CSS3新增

李南江的前端课程知识点(十)补充CSS3新增

a标签的伪类选择器a标签存在一定的状态:1、默认状态,从未被访问。2、被访问过的状态。3、鼠标长按状态。4、鼠标悬停在a标签上的状态。a标签的伪类选择器就是专门用来修改a标...

星中媛 阅读(321)

Java Thread Join 线程插队

packagecom.chenxb.myThread;publicclassTestJoinimplementsRunnable{@Overridepublicvoidrun(){for(in...

chen183945653 阅读(963)

Hive经典面试题之【自连接,行转列,列转行】

1.hive自连接现有这么一批数据,现要求出:每个用户截止到每月为止的最大单月访问次数和累计到该月的总访问次数三个字段的意思:用户名,月份&#x...

故事Dome 阅读(652)

力扣11. 盛最多水的容器

classSolution{publicintmaxArea(int[]height){intleft=0;intright=height.length-1;intarea=0...

邓瞻 阅读(174)

Nginx配置ip_hash导致负载均衡算法失效解决方法

文章目录问题简述解决问题在http标签里面添加下面属性在server标签里的location里面添加以下内容重新启动nginx问题简述由于公司的老项目用的架构属于前端后台在一起web项目,为了保证多机...

陌筱明 阅读(250)