一甜攀、功能和亮點
- 點擊焦點EditText外秋泄,攔截觸摸事件且收起鍵盤琐馆;
- 點擊焦點EditText外,正常下發(fā)觸摸事件且收起鍵盤恒序;
- 點擊焦點EditText外瘦麸,正常下發(fā)觸摸事件但不收起鍵盤;
- 鍵盤彈出時歧胁,可正常進(jìn)行滑動事件
- 50行以內(nèi)代碼量
- 一行代碼調(diào)用滋饲,實現(xiàn)最低業(yè)務(wù)入侵
二、代碼
class GestureDetectorHolder(val activity: Activity) {
var excludeViews = hashSetOf<View>()
private val detector: GestureDetector by lazy {
var isIntercept = false
object : GestureDetector(activity, object : GestureDetector.SimpleOnGestureListener() {
val outRect = Rect()
override fun onDown(e: MotionEvent): Boolean {
return activity.currentFocus is EditText && excludeViews.apply {
add(activity.currentFocus)
}.all {
outRect.apply {
it.getGlobalVisibleRect(this)
}.let { !it.contains(e.x.toInt(), e.y.toInt()) }
}.also {
isIntercept = it
}
}
override fun onSingleTapUp(e: MotionEvent): Boolean {
return isIntercept.apply {
(activity.currentFocus as? EditText)?.takeIf { this }?.apply {
closeInputMethodAndClearFocus()
}
}
}
override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
if (isIntercept) {
isIntercept = false
e2.action = ACTION_DOWN
e2.setLocation(e1.rawX, e1.rawY)
}
return false
}
}){
override fun onTouchEvent(ev: MotionEvent): Boolean {
return activity.currentFocus.let { if (it != null)WindowUtils.isInputVisible(it) else false } and super.onTouchEvent(ev)
}
}.also {
it.setIsLongpressEnabled(false)
}
}
fun dispatchMotionEvent(event: MotionEvent, vararg views: View?):Boolean {
return !detector.onTouchEvent(event) || Rect().let {rect->
views.filterNotNull().any {
rect.setEmpty()
it.getGlobalVisibleRect(rect)
rect.contains(event.x.toInt(), event.y.toInt())
}
}
}
}
三喊巍、使用方法
重寫Activity.dispatchTouchEvent(ev: MotionEvent): Boolean方法屠缭,由GestureDetectorHolder.dispatchMotionEvent(ev: MotionEvent, vararg views: View?): Boolean代理實現(xiàn)
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
return GestureDetectorHolder(this).apply {
excludeViews = hashSetOf(editAddress, editNotes, editContent)
}.dispatchMotionEvent(ev, iftActionLeft, iftActionRight) && super.dispatchTouchEvent(ev)
}
excludeViews:gestureDetectorHolder將忽略這些View,當(dāng)鍵盤彈出時崭参,點擊這些View正常下發(fā)觸摸事件勿她,且不收起鍵盤
dispatchMotionEvent(event: MotionEvent, vararg views: View?):
views:gestureDetectorHolder將特殊處理這些View,當(dāng)鍵盤彈出時阵翎,點擊這些View正常下發(fā)觸摸事件,但收起鍵盤
其他區(qū)域:攔截觸摸事件之剧,且收起鍵盤
四郭卫、EditText失焦隱藏光標(biāo)
fun View.openInputMethod() {
if (!isFocused) {
isFocusable = true
isFocusableInTouchMode = true
requestFocus()
(this as? EditText)?.isCursorVisible = true
postDelayed({
(context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager).showSoftInput(this, SHOW_FORCED)
}, 100)
}
}
fun View.closeInputMethod() {
(context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(windowToken, 0)
}
fun EditText.closeInputMethodAndClearFocus() {
closeInputMethod().apply {
isCursorVisible = false
isFocusable = false
isFocusableInTouchMode = false
clearFocus()
}
}