Android中事件的传递
首先来张图看看
1. 核心方法返回值的含义
dispatchTrackballEvent 分发事件
public boolean dispatchTrackballEvent(MotionEvent event)
如果 return true,事件会分发给当前 View 并由 dispatchTouchEvent 方法进行处理,同时事件会停止向下传递;
如果 return false,事件分发分为两种情况:
如果当前 View 获取的事件直接来自 Activity,则会将事件返回给 Activity 的 onTouchEvent 进行消费;
如果当前 View 获取的事件来自外层父控件,则会将事件返回给父 View 的 onTouchEvent 进行消费。
如果返回系统默认的 super.dispatchTouchEvent(ev),事件会自动的分发给当前 View 的 onInterceptTouchEvent 方法。
onInterceptTouchEvent 拦截事件(只有ViewGroup有)
public boolean onInterceptTouchEvent(MotionEvent ev)
返回true 拦截 ;false 不拦截
如果 onInterceptTouchEvent 返回 true,则表示将事件进行拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理;
如果 onInterceptTouchEvent 返回 false,则表示将事件放行,当前 View 上的事件会被传递到子 View 上,再由子 View 的 dispatchTouchEvent 来开始这个事件的分发;
如果 onInterceptTouchEvent 返回 super.onInterceptTouchEvent(ev),事件默认会被拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理。
onTouchEvent 处理事件
public boolean onTouchEvent(MotionEvent event)
返回true 自己处理 ;false传递给下一个处理
该方法的返回值是提供给dispatchTouchEvent()的返回值
ViewGroup中的事件处理的发放
/**
*分发事件
* @param event 事件
*/
@Override
public boolean dispatchTrackballEvent(MotionEvent event) {
return super.dispatchTrackballEvent(event);
}
/**
*拦截事件
* @param event 事件
* @return 返回true 拦截 ;false 不拦截
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.d(TAG, "是否拦截");
//让viewDragHelper帮主我们判断是否应该拦截
return viewDragHelper.shouldInterceptTouchEvent(ev);
}
/**
*处理事件
* @param event 事件
* @return 返回true 自己处理 ;false传递给下一个处理
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(TAG, "onTouchEvent");
//让ViewDragHelper帮主我们处理触摸事件
viewDragHelper.processTouchEvent(event);
return true;
}
事件的分类
Android使用MotionEvent对于触摸事件进行描述
事件分类
- 按下
- 移动
- 弹起
事件传递的原则
- 按下事件一定要传递到最底层
- 那一层没有处理按下事件,其他的事件也不会传递进该层(只针对控件,不针对Activity)
- Activity、Viewgroup、View默认本身是不会处理任何事件的
点击事件一定要强制传递到最底层,不然子控件请求父控件不要拦截方法执行不到
效果处理放置在onTouchEvent()
子控件请求父控件不要拦截事件
就是在MyView层的dispatchTouchEvent方法中请求父控件不要拦截
事件拦截的代码应该写在哪里?
如果ViewGroup要拦截事件,拦截的逻辑处理放置在onInterceptTouchEvent()