天天看点

安卓隐藏输入法键盘以及去除光标方法

在开发中遇到一个需求“点击屏幕非编辑区以及点击键盘回车键后要隐藏输入法以及光标要关闭”,因此向各位分享一下做法

一.点击屏幕处于非edittext时让键盘消失以及清除edittext光标方法:

         1.在Activity中使用如下代码:

  1.    @Override
  2.    public  boolean dispatchTouchEvent(MotionEvent ev) {
  3.         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
  4.             View v = getCurrentFocus();
  5.             if (isShouldHideKeyboard(v, ev)) {
  6.                v.clearFocus();//清除Edittext的焦点从而让光标消失
  7.                hideKeyboard(v.getWindowToken()); 
  8.             }
  9.         }
  10.         return super.dispatchTouchEvent(ev);
  11.    }
  12.    private boolean isShouldHideKeyboard(View v, MotionEvent event) {
  13.         if (v !=null && (vinstanceof EditText)) {
  14.             int[] l = {0, 0};
  15.             v.getLocationOnScreen(l);;
  16.             int left = l[0],
  17.                 top = l[1],
  18.                 bottom = top + v.getHeight(),
  19.                 right = left + v.getWidth();
  20.             if (event.getRawX() > left &&event.getRawX() < right
  21.                     && event.getRawY()> top && event.getRawY() < bottom) {
  22.                 //点击EditText的时候不做隐藏处理
  23.                 return false;
  24.             } else {
  25.                 return true;
  26.             }
  27.         }
  28.         //如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditText上,和用户用轨迹球选择其他的焦点
  29.         return false;
  30.    }
  31.    private void hideKeyboard(IBindertoken) {
  32.         if (token !=null) {
  33.         //若token不为空则获取输入法管理器使其隐藏输入法键盘
  34.             InputMethodManager im =(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
  35.             im.hideSoftInputFromWindow(token,InputMethodManager.HIDE_NOT_ALWAYS);
  36.         }
  37.     }

2.上面代码实现后然而只能做到隐藏键盘,但是EditText的光标仍然未消去,原因并不是clearFocus()无效,而是虽然调用了clearFocus()方法,但是由于失去焦点后系统会重新获取焦点,此时焦点又重新给到了EditText,所以光标看上去就是没有消去,所以我们需要让一个在EditText之前的控件去抢焦点,这样子就不会出现上述问题。此处可以直接在layout中的根布局加入焦点属性说明:android:focusableInTouchMode="true"

例子:

  1. <RelativeLayout     xmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:tools="http://schemas.android.com/tools"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:focusableInTouchMode="true"
  6.     android:background="@android:color/white"
  7.    >
  8.     <EditText
  9.           android:id="@+id/ed"
  10.           android:layout_width="match_parent"
  11.           android:layout_height="wrap_content"
  12.           android:inputType="text"
  13.       />
  14. </RelativeLayout>

二.当输入完成后点击回车键后让键盘和光标消失方法

1.当我们用输入法中的回车时可以使用EditText中的setOnKeyListener接口回调对相应按键事件进行处理:

例子:

  1. ed.setOnKeyListener(newOnKeyListener() {
  2.         @Override
  3.     public boolean onKey(View v, int keyCode,KeyEvent event) {
  4.                 // TODO Auto-generated methodstub
  5.                 //若接收到回车键时候失去焦点,隐藏输入法
  6.             if (keyCode == KeyEvent.KEYCODE_ENTER){
  7.                       ed.clearFocus();
  8.                       InputMethodManager im = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
  9.                       im.hideSoftInputFromWindow(v.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
  10.                       return true;
  11.                 }
  12.                 return false;
  13.             }
  14.         });

注意:若设置了Edittext的imeOptions属性为非normal(即非默认)的情况下,此时可能收不到相应的回调因此无法执行此处方法

 补充----若定义为别的imeOptions则需要使用OnEditorActionListener

  1. ed.setOnEditorActionListener(new OnEditorActionListener() {
  2.             @Override
  3.             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
  4.                 if(actionId == EditorInfo.IME_ACTION_SEARCH){ //actiondId 即我们设置的imeOptions对应的id  
  5.                ed.clearFocus();
  6.               InputMethodManager im = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
  7.               im.hideSoftInputFromWindow(v.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
  8.                     return true;
  9.                 }
  10.                 return false;
  11.             }
  12.         });

2.同样的clearFocus()可能无法正常去除光标,做法参照上面,在根布局中去抢焦点。