android_事件分发机制_几行代码直接通晓

/**
 * View的事件分发
 */
public class View{


public boolean dispatchTouchEvent(MotionEvent ev){
boolean result = false;


// 先判断是否设置了onTouchListener,如果设置了,就调用
if (mOnTouchListener != null && mOnTouchListener.onTouch(ev)) {
result = true;
}


// 如果没有设置onTouchListener,或者调用了onTouch后返回了false,那么就调用onTouchEvent
if (!result && onTouchEvent(ev)) {
result = true;
}
return result;
}


public boolean onTouchEvent(MotionEvent ev){


// 如果View可点击
if (isClickable()) {
switch (ev.getAction()) {
...
case MotionEvent.ACTION_UP:
...
// 判断是否设置了onClickListener,设置了就调用,并消耗事件
if (mOnClickListener != null) {
mOnClickListener.onClick(this);
}
...
break;
...
}
// 可点击的View,默认会消耗掉事件
return true;
}
// 不可点击的View,默认不消耗事件
return false;
}
}




/**
 * ViewGroup的事件分发
 */
public class ViewGroup extends View{


// 一旦有子元素消耗了事件,这个子元素就被赋值给mFirstTouchTarget
public View mFirstTouchTarget = null;


public boolean dispatchTouchEvent(MotionEvent ev){
int action = ev.getAction();
boolean handled = false;
boolean intercepted;


// DOWN事件,或者有子元素消耗事件,则进入if语句内,判断是否拦截
if (action == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {
// 取出 是否允许拦截 的标记,默认是false。子元素可以通过requestDisallowInterceptTouchEvent(true);将这个标记设置为true
boolean disallow = getFlagDisallowIntercept();


if (!disallow) {
// 允许拦截,调用onInterceptTouchEvent判断是否拦截
intercepted = onInterceptTouchEvent(ev);
}else {
// 不允许拦截,直接不拦截
intercepted = false;
}
}else {
// 非DOWN事件,或者没有子元素消耗了事件,直接拦截
intercepted = true;
}


// 如果有子元素消耗事件,alreadyDispatched就被赋值为true
boolean alreadyDispatched = false;


if (!intercepted) {
// 不拦截事件


// 遍历子元素
for (int i = 0 ; i < mChildList().size() ; i++) {
View child = mChildList.get(i);
float x = ev.getX();
float y = ev.getY();


if (x >= child.left && x <= child.right && y >= child.top && y <= child.bottom) {
// 事件位于子元素所在区域内,将事件分发给子元素


if (child.dispatchTouchEvent(ev)) {
// 子元素消耗了事件


mFirstTouchTarget = child;
alreadyDispatched = true;


// 跳出循环,不再分发
break;
}
}

}
}


if (mFirstTouchTarget == null) {
// 没有子元素消耗事件
// ViewGroup自行处理事件
super.dispatchTouchEvent(ev);

}else {
// 有子元素消耗了事件,则后续事件全部交给该子元素处理,不管他是否消耗事件
if (alreadyDispatched) {
mFirstTouchTarget.dispatchTouchEvent(ev);
handled = true;
}
}


return handled;
}


public boolean onTouchEvent(MotionEvent ev){
super.onTouchEvent(ev);
}


public boolean onInterceptTouchEvent(MotionEvent ev){
return false;
}
}

你可能感兴趣的:(android)