Android View事件分发机制
2020-03-24 本文已影响0人
VincentStory
事件分发对象:
Activity: 控制生命周期&处理事件
ViewGroup:一组view的集合(包含多个子view)
View:所有UI组件的基类
事件分发主要方法:
dispatchTouchEvent(MotionEvent ev):用来进行事件分发
onInterceptTouchEvent(MotionEvent ev): 判断是否拦截事件(只存在于viewGroup中)
onTouchEvent(MotionEvent ev):处理点击事件
根据不同情况有两种拦截方法,一种是外部拦截法,就是当viewgroup需要处理touch事件的时候,重写viewgroup的onInterceptTouchEvent()方法,设置拦截事件。
第二种是内部拦截法,就是当子view需要处理touch事件时候,viewgroup已经拦截了事件,所以需要告诉子view需要通过requestDisallowInterceptTouchEvent()方法告诉viewgroup不要拦截事件,由子view自身去处理事件。
外部拦截法
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercepted = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
intercepted = false;//必须false,否则后续的MOVE和UP不再传递给子View
break;
case MotionEvent.ACTION_MOVE:
if(父容器需要当前点击事件){
intercepted=true;
}else{
intercepted=false;
}
break;
case MotionEvent.ACTION_UP:
intercepted=false;//必须false,会影响子view的onclick是否被触发
break;
}
return intercepted;
}
内部拦截法
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean intercepted = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//关闭父容器的拦截功能
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
if(父容器需要此类点击事件){
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
break;
}
return super.dispatchTouchEvent(ev);
}
流程图:
touch_event.png总结:
touch事件-->Activity dispatchTouchEvent --> ViewGroup dispatchTouchEvent -->ViewGroup onInterceptTouchEvent -->如果拦截 就自身处理touch事件,如果不拦截,事件传递到子view dispatchTouchEvent, 子view如果继续分发,那就是子view自己处理touch事件,如果不分发,那就交给父容器的onTouchEvent处理事件。