控件与布局分别继承view和groupView
首先图如下:为touch事件的流程图:
学习这个消费机制需要从源码着手:
-----------------------------------------------------------
首先是view处理机制:
我们首先从dispatchTouchEvent事件开始查询:这是系统默认的分发事件的规则,一切touch事件的源头。
View中dispatchTouchEvent(ev)
因此 我们注意也就是第二个if条件
我们就拿imageview和button两个点击事件传递为例:
代码如下:
imageView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//返回false,当前只会去打印一次
//返回true,打印两次
//0 是down 1是up
System.out.println("imageView----------onTouch"+event.getAction());
return false;
}
});
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//返回false,打印两次
//返回true,打印两次,如果在此处返回true,则不会去调用onTouchEvent
//则button不会去响应onclick事件,因为onclick方法在onTouchEvent方法中去调用,
//0 是down 1是up
System.out.println("Button----------onTouch"+event.getAction());
return false;
}
});
mOnTouchListener:
也就是它就是
<pre name="code" class="java">控件所设置setOnTouchListener( new OnTouchListener() <span style="font-family: Arial, Helvetica, sans-serif;">这个对象 所有部位null 返回true</span>
</pre><pre>
(mViewFlags & ENABLED_MASK) == ENABLED:控件都是可使用的 返回true
mOnTouchListener.onTouch(this, event):最后这就是你在控件
new OnTouchListener() 最后 return false还是true 则返回相应的。上面代码 我返回都是false
所有最后也返回false 这样因为一个false 执行了return onTouchEvent(event);
接下来我们查看 onTouchEvent事件:
主要看这段:
可以点击,执行里面的代码: return true 消费了整个touch事件
if (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
...
case MotionEvent.ACTION_DOWN:
...
case MotionEvent.ACTION_CANCEL:
...
case MotionEvent.ACTION_MOVE:
...
}
return true;
}
return false;
}
判断是否可用点击或者长按:代码如下:
if (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE))
可以点击,执行里面的代码: return true 消费了整个touch事件
不可点击,return false 不会消费touch事件
然后是GroupView处理机制:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
....
if (action == MotionEvent.ACTION_DOWN) {
//将当前的mMotionTarget一直赋值为空
if (mMotionTarget != null) {
mMotionTarget = null;
}
if (disallowIntercept || !onInterceptTouchEvent(ev)) {
//如果当前onInterceptTouchEvent返回false进入当前逻辑段
//1,获取当前viewgroup中所有的子节点
//2,循环便利所有子节点,判断当前点击的位置在那个子节点内部
//3,假设找到点中子节点(如果是viewgroup则,一直循环此操作(onInterceptTouchEvent方法一直返回的是false),直至找到view的时候位置)
//4,通过view的事件处理方式去处理当前子控件
}
}
...
final View target = mMotionTarget;
if (target == null) {
...
//调用view的事件处理规则
return super.dispatchTouchEvent(ev);
}
...
}
public boolean dispatchTouchEvent(MotionEvent ev) {
....
if (action == MotionEvent.ACTION_DOWN) {
//将当前的mMotionTarget一直赋值为空
if (mMotionTarget != null) {
mMotionTarget = null;
}
if (disallowIntercept || !onInterceptTouchEvent(ev)) {
//如果当前onInterceptTouchEvent返回false进入当前逻辑段
//1,获取当前viewgroup中所有的子节点
//2,循环便利所有子节点,判断当前点击的位置在那个子节点内部
//3,假设找到点中子节点(如果是viewgroup则,一直循环此操作(onInterceptTouchEvent方法一直返回的是false),直至找到view的时候位置)
//4,通过view的事件处理方式去处理当前子控件
}
}
...
final View target = mMotionTarget;
if (target == null) {
...
//调用view的事件处理规则
return super.dispatchTouchEvent(ev);
}
...
}