由于最近比较忙,而且没有发现好玩的萌动小动画,所以就没有更新。争取在年前给大家更新(实在没有发现很萌的小动画,有发现好玩的小动画的小伙伴可以发我)。现在先更新一个小工具类(小伙伴们不要忘记我啊)!!
在使用APP
时,当点击输入框弹出键盘后,点击非输入框区域收起键盘是非常好的体验。但是在实际使用中,我们可以发现Android APP
中大部分APP
没有实现该功能,都需要点击返回键或者键盘收起。那么,是不是实现起来很麻烦呢?有些小伙伴可能会觉得有点麻烦,因为用到键盘的地方很多,而且要实现该功能是要监听所有的控件,要一个个控件写上监听。那有没有办法简单的方法实现的该功能?有的!国际惯例,我们先来看一下效果。
通过图片可以发现,只要触摸非EditText
区域就会关闭键盘,并且取消EditText
的Fcous
,效果很符合我们平时的需求。
使用方法也很简单,只需要在需要实该功能的Activity
中添加以下代码即可:
private val mTouchEmptyCloseKeyBoardUtils:TouchEmptyCloseKeyBoardUtils by lazy {
TouchEmptyCloseKeyBoardUtils()
}
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
mTouchEmptyCloseKeyBoardUtils.autoClose(this, ev)
return super.dispatchTouchEvent(ev)
}
看完了使用方法,我们现在来分析一下实现。
因为点击事件在传递给布局之前会先到达Activity
的dispatchTouchEvent()
方法中,所以我们可以在这里对触摸事件进行处理。
通过autoClose()
方法的代码我们可以发现,我们只需要在down
事件的时候对事件进行处理。首先先获取当前activity
的focusView
和DectorView
对象。然后在28行调用judgeIsTouchInView()
方法判断是否点击在DectorView
上,如果不是则不进行处理。然后递归调用getChild()
方法获取第一个获得该点击事件的View
,如果判断点击的View
不是EditText
则关闭键盘,并取消focusView
的焦点。
judgeIsTouchInView()
的实现也很简单,首先通过View.getLocationInWindow()
方法获取view
在window
上的x、y
坐标,然后加上该View
的宽高获得该View
在window
上的矩形区域,然后判断点击区域是否在View
所在的矩形上即可。
getChild()
方法首先判断传入的ViewGroup
有没有子View
,没有则返回当前ViewGroup
。如果有子View
,则遍历子View
,判断该View
是否在点击区域上。如果是,则判断该View
是不是ViewGroup
,如果是ViewGroup
则递归调用getChild()
方法,如果是View
的话则通过getTouchables()
方法判断该View
是否是可以Touch
的,是就返回该View
。
通过以上代码,我们就实现了点击非输入框收起键盘的功能。
我们下篇文章见,See you !