view的事件分发
事件MotionEvent常见类型:ACTION_DOWN、ACTION_MOVE、ACTION_UP
事件分发相关函数:dispatchTouchEvent、nInterceptTouchEvent、onTouchEvent
onTouchListener(onTouch)、onClickListener(onClick)
事件传递顺序:Activity--ViewGroup--View
(其实Activity和ViewGroup中还有Window,Window的唯一实现是PhoneWindow,事件会传递到顶级View即DecorView中,DecorView继承自FrameLayout,是个Viewgroup)
流程
1、Activity:
1、dispatchTouchEvent:
返回值,return
1、super.dispatchTouchEvent(ev):事件向下传递,调用ViewGroup或View的dispatchTouchEvent
注意,理解好这个向下传递,如果事件点击在子ViewGroup或View所在的区间,那么
向下传递,就是传到它们的dispatchTouchEvent,否则向下传递就是传到自身的
onTouchEvent,下面的ViewGroup的向下传递原理类似
2、true:事件消费,传递终止
3、false:事件不消费,向下传递终止,是否有向上传递?
2、onTouchEvent:
1、super.onTouchEvent(event):不知道默认是否消费事件,但这是最上层的onTouchEvent,之后的事件会直接传递到此函数
2、true:消费事件,之后的事件会直接传递到此函数
3、false:不消费事件,之后的事件依然会直接传递到此函数
注意,这个函数只有在以下三种情况下才会调用,而且调用过一次后,后面的事件经过Acivity的dispatchTouchEvent后,
就会直接调用这个函数,不再进行向下传递
1、下一级的ViewGroup或View的dispatchTouchEvent函数返回false
2、下一级的ViewGroup或View的onTouchEvent函数返回false
3、下一级的ViewGroup函数返回super.onTouchEvent(event)
2、ViewGroup:
1、dispatchTouchEvent:
1、super.dispatchTouchEvent(ev):事件向下传递,调用ViewGroup的onInterceptTouchEvent
2、true:事件消费,终止传递
3、false:事件不消费,终止向下传递,向上传递,调用Activity的onTouchEvent
2、onInterceptTouchEvent:
1、super.onInterceptTouchEvent(ev):事件向下传递,调用View的dispatchTouchEvent
纠正,会看情况是否向下传递,比如下面的网址说的情况,这个返回值就不向下传递
那就是true,
https://zhidao.baidu.com/question/981857480840100339.html?skiptype=2
2、true:事件拦截,调用ViewGroup的onTouchEvent
3、false:事件不拦截,向下传递,调用View的dispatchTouchEvent,这里等同于super.onInterceptTouchEvent(ev)?
看上面的纠正,super.onInterceptTouchEvent(ev)不一定返回false,视情况而定,比如上面网址的例子就不向下传递
3、onTouchEvent:
1、super.onTouchEvent(event):默认是事件不消费?调用Activity的onTouchEvent,之后的事件不会再传递到ViewGroup进行处理
注意里与View的这一返回值进行区别,View的这一返回值一般默认是消费的,而ViewGroup的这一
返回值一般默认是不消费的,也很好理解
2、true:事件消费,终止传递,之后的事件会Activity--ViewGroup
注意,之后的事件既不会再向下传递,即不会再传递到View,也不会再调用ViewGroup的onInterceptTouchEvent
3、false:事件不消费,向上传递,调用Activity的onTouchEvent,之后的事件不会再传递到ViewGroup进行处理
注意,这个函数在以下三种情况下才会调用,而且调用过一次后,之后的事件不再向下传递,也不会再调用ViewGroup的onInterceptTouchEvent
1、ViewGroup的onInterceptTouchEvent返回true
2、View的dispatchTouchEvent返回false
3、View的onTouchEvent返回false
3、View:
1、dispatchTouchEvent:
1、super.dispatchTouchEvent(ev):事件向下传递,调用View的onTouchEvent,之后的事件还会依次Activity--ViewGroup--View
2、true:事件消费,终止传递,之后的事件还会依次Activity--ViewGroup--View
3、false:事件不消费,终止向下传递,向上传递,调用ViewGroup的onTouchEvent,之后的事件不会再传递到View进行处理
2、onTouchEvent:
1、super.onTouchEvent(event):默认是事件消费?之后的事件还会依次Activity--ViewGroup--View
比如继承一个Button,一般像Button这样带点击功能的View的onTouchEvent都会
消费掉事件
2、true:事件消费,之后的事件还会依次Activity--ViewGroup--View
3、false:事件不消费,向上传递,调用ViewGroup的onTouchEvent,之后的事件不会再传递到View进行处理
注意,这个函数在以下一种情况下才会调用,
1、View的dispatchTouchEvent函数返回super.dispatchTouchEvent(ev)
额外的两个函数
1、onTouch:
1、在哪调用
在定义ViewGroup或View变量的Activity或Fragment中调用
testLinearLayout或testButton
.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i(SjffActivity.TAT, "TestButton-onTouch-ACTION_DOWN...");
break;
case MotionEvent.ACTION_UP:
Log.i(SjffActivity.TAT, "TestButton-onTouch-ACTION_UP...");
break;
default:
break;
}
return false;
}
});
2、什么时候被调用
一定是在上述流程中,ViewGroup或View的onTouchEvent函数被调用的情况下,相应的onTouch函数才能被调用,
而且,onTouch函数先于onTouchEvent函数被调用,注意onTouch函数被调用情况下,onTouchEvent函数不一定能被调用
3、返回值
1、false:则onTouchEvent函数接着会被调用,
2、true:则onTouchEvent函数不会被调用
2、onClick
1、在哪调用
在定义ViewGroup或View变量的Activity或Fragment中调用
testLinearLayout或testButton
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(SjffActivity.TAT, "TestButton---onClick...");
}
});
2、什么时候被调用
一定是在上述流程中,ViewGroup或View的onTouchEvent函数被调用的情况下,相应的onClick函数才能被调用,
而且,onClick函数后于onTouchEvent函数被调用,注意onClick函数被调用情况下,onTouchEvent函数一定先被调用了
注意,onClick函数是在ACTION_UP事件后才被调用,即手指抬起的时候才被调用,与onTouch的事件监听不同
3、返回值
onClick本身没有返回值,但是一旦testLinearLayout或testButton设置了.setOnClickListener,
则相应的onTouchEvent函数就会返回true,即消费了事件