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

来源:互联网 发布:域名需要解析吗 编辑:程序博客网 时间:2024/06/18 18:41

背景

仿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代后续更新

阅读全文
0 0