您的位置:首页 > 移动开发 > Android开发

Android 滑动与点击事件冲突的处理

2017-11-13 21:56 330 查看

背景

仿IOS 实现一个列表项左滑动删除的功能,用一个LinearLayout加上GestureDetector来实现滑动,LinearLayout中的子view添加点击事件,父view的滑动事件与子view点击事件如何优雅的处理?

思路

android 中事件分发机制中,有3个关键的方法,dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent,具体他们如何使用的,以后有空再给大家介绍。

说明:在父类中分发、拦截处理事件,因为在该场景中,可能会扩展多个按钮(与删除并列),为了扩性,由父View统一处理。

首先,在负责消息分发的dispatchTouchEvent中,将消息同时分发给mGestureDetector.onTouchEvent(ev)

其次,在onInterceptTouchEvent中,不拦截down和move事件,只拦截up事件即可,因为up事件是子view是否执行点击操作的关键

最后,在GestureDetector.OnGestureListener.onScoll()方法中判断是否产生滑动,如果滑动了,则拦截up事件;如果没有滑动,则传递up事件到子view,从而长生点击


实现

代码用kotlin写的,17年Google开发者大会强推的语音,语法挺简单的,关键代码如下:

override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean {
if (Math.abs(distanceX) < MIN_DISTANCE) {
// 如果滑动小于最小滑动距离
return true
} else {
mHasScroll = true
}
return true
}

override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
//将事件传递给GestureDetector
mGestureDetector.onTouchEvent(ev)
return super.dispatchTouchEvent(ev)
}

override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
if (ev != null && ev!!.action == MotionEvent.ACTION_DOWN){
mHasScroll = false
}else if (ev != null && mHasScroll && ev!!.action == MotionEvent.ACTION_UP) {
//如果产生了滑动,则不传递事件到子view了
return true
}
return super.onInterceptTouchEvent(ev)
}


总结

事件统一由父类分别分发给滑动和点击,如果有滑动,则将up事件给拦截;如果无滑动,则由子view出发点击。

本文仅介绍此情况下滑动与点击冲突时如何处理,完整demo代后续更新
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android 滑动冲突