目前SlidingMenu使用很常见,也很方便,下面对SlidingMenud的事件处理机制进行一下简单的分析:
介绍:
SlidingMenu分为SlidingMenu.java, CustomViewBehind.java, CustomViewAbove.java,核心文件
SlidingMenu.java继承自RelativeLayout类,包含CustomViewBehind.java,CustomViewAbove.java,两个View,
CustomViewBehind.java继承自ViewGroup,作为后面显示的菜单View
CustomViewAbove.java继承自ViewGroup,作为前面显示的主View,
事件:
当菜单项隐藏时
当用户操作View也就是CustomViewAbove时,事件首先由上向下分发
ACTION_DOWN
1.SlidingMenu-->dispatchTouchEvent-->onInterceptTouchEvent
2.CustomViewAbove-->dispatchTouchEvent-->onInterceptTouchEvent 是否拦截,如果拦截调用本类的onTouchEvent,如果不拦截,继续向CustomViewAbove子类传递,一直传递到最里层View,当有View的onTouchEvent返回TRUE时,结束事件传递以后事件就直接分发给该view,如果没有事件回传给上层View的onTouchEvent,一般底层都有可能有事件拦截
3.此时事件不会传递到CustomViewBehind。因为这个View为不可见状态
ACTION_MOVE
事件传递原理同上,不同之处在于
1.CustomViewAbove-->dispatchTouchEvent-->onInterceptTouchEvent 会判断手势是否是滑动(如左)如果不是返回false不拦截,表明是点击事件,如果符合滑动规则返回true拦截事件,就会调用本类的onTouchEvent,处理滑动事件,移动View,展现后面菜单。
ACTION_UP
1.CustomViewAbove 如果是移动事件抬起,恢复或者展开菜单
当菜单展开时,点击右边的CustomViewAbove,事件处理如下
ACTION_DOWN
1.SlidingMenu-->dispatchTouchEvent-->onInterceptTouchEvent
2.CustomViewAbove-->dispatchTouchEvent-->onInterceptTouchEvent 判断是否是点击了右边的CustomViewAbove,如果是的,认为是想关闭菜单,设置快速关闭变量为true,返回true拦截事件,调用本类的onTouchEvent方法,返回true,后面的事件就传递给本类
3.事件不会传递到CustomViewBehind,因为事件被拦截
ACTION_MOVE
同上,区别
1.CustomViewAbove中的onTouchEvent 判断滑动的方向,符合条件,开始滑动
ACTION_UP
如果快速关闭变量为true,关闭菜单
当菜单展开时,点击右边的CustomViewAbove也就是菜单时 ,事件处理如下
ACTION_DOWN
1.SlidingMenu-->dispatchTouchEvent-->onInterceptTouchEvent
2.CustomViewAbove -->dispatchTouchEvent-->onInterceptTouchEvent 判断是不是拦截
3.CustomViewBehind-->dispatchTouchEvent-->onInterceptTouchEvent 不做处理
ACTION_MOVE,ACTION_UP
同上,区别
事件直接传递给子ViewGroup
需求:
有时候我们希望滑动菜单项也可以关闭菜单
设置,setTouchModeBehind(SlidingMenu.TOUCHMODE_FULLSCREEN);可是点击菜单项就没有反应了,
问题是,
事件传递到CustomViewAbove -->onTouchEvent 被它拦截了,事件就传递不到CustomViewBehind,所有点击事件被拦截了,
解决的方法:
当菜单打开时候,CustomViewAbove -->onTouchEvent 不要拦截事件,事件传递给CustomViewBehind,在CustomViewBehind的onInterceptTouchEvent 方法中判断是不是滑动如果是滑动,拦截事件,交给onTouchEvent 处理滑动