简单了解事件的触发机制
在Android中,View的结构是树状的,所以,当触发触摸事件的时候,其事件传递也是从上之下一层层的传递。下面我们结合例子来一点点进行分析。
首先,我们需要了解事件处理中的几个方法:
1、在ViewGroup中,事件分为dispatchTouchEvent(事件的分发),onInterceptTouchEvent(事件的拦截),onTouchEvent(事件的处理)。
2、在View中,事件分为dispatchTouchEvent(事件的分发),onTouchEvent(事件的处理)。
关闭软键盘思路
1、监听整个页面的事件分发(即ViewGroup中的dispatchTouchEvent)
2、用getCurrentFocus()方法获取当前焦点所在的view,以及在其父窗口中的坐标位置
3、根据EditText所在坐标和用户点击的坐标相对比,判断是否点击的区域在EditText的区域范围内
效果图
相关代码
事件分发
@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {if (ev.getAction() == MotionEvent.ACTION_DOWN) {View v = getCurrentFocus();if (isShouldHideKeyboard(v, ev)) {hideKeyboard(CloseSoftKeyBoard.this,Objects.requireNonNull(v).getWindowToken());}}return super.dispatchTouchEvent(ev);}
判断点击的区域是否需要关闭软键盘
/*** 根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘,因为当用户点击EditText时则不能隐藏*/public static boolean isShouldHideKeyboard(View v, MotionEvent event) {if (v != null && (v instanceof EditText)) {int[] l = {0, 0};v.getLocationInWindow(l);//得到输入框在屏幕中上下左右的位置int left = l[0], top = l[1], bottom = top + v.getHeight(), right = left + v.getWidth();if (event.getX() > left && event.getX() < right && event.getY() > top && event.getY() < bottom) {// 点击位置如果是EditText的区域,忽略它,不收起键盘。return false;}else {return true;}}return false;}
关闭软键盘
/*** 获取InputMethodManager,隐藏软键盘*/public static void hideKeyboard(Activity activity, IBinder token) {if (token != null) {InputMethodManager im = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);Objects.requireNonNull(im).hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);}}