Android——View的触摸传递机制

来源:互联网 发布:我的淘宝流量入口 编辑:程序博客网 时间:2024/06/07 22:47

Android View触摸事件传递机制

触摸事件主要有三种且执行顺序为:ACTION_DOWN,ACTION_MOVE,ACTION_UP。也就

是先执行ACTION_DOWN按下的行为,按下之后手指可能会移动,移动时就出发了

ACTION_MOVE行为,当手指抬起时,触发了ACTION_UP行为,至此触摸事件顺序执行结

束。当然触摸事件不止这三种行为,但是我们这里主要分析这三种。

触摸事件过程执行的方法顺序为:dispatchTouchEvent,onTouch,onTouchEvent。最后执

行了onClick点击事件。也就是顺序应该为:dispatchTouchEvent–>>onTouch–>>onTouchEvent–>>onClick

onClick点击事件是在触摸事件ACTION_UP执行完之后才执行。

public boolean dispatchTouchEvent(MotionEvent event) {        if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&                mOnTouchListener.onTouch(this, event)) {            return true;        }        return onTouchEvent(event);    }

分析:方法实现很简单,当满足if条件就返回true退出方法,条件不满足时,才去执行

onTouchEvent方法且返回该方法的返回值。

1.那么什么情况下满足mOnTouchListener != null条件呢?查看View源码发现调用如下方法时:

public void setOnTouchListener(OnTouchListener l) {        mOnTouchListener = l;    }

当开发者给相应的View设置了View#setOnTouchListener触摸事件之后,mOnTouchListener != null条件就成立。

2.View默认都是enabled状态,所以第二个条件成立。

3.当前两个条件都成立了,执行第三个条件接口方法mOnTouchListener.onTouch(this,

event)。根据该方法的返回值来决定if条件是否成立。该方法在开发者设置

View#setOnTouchListener触摸事件实现,当onTouch方法返回false时,

dispatchTouchEvent方法就会执行onTouchEvent方法,否则不执行onTouchEvent方法。

总结:

1.onTouch接口方法的返回值决定是否执行onTouchEvent方法。

2.只要onTouch接口方法返回值为true,dispatchTouchEvent方法一定返回true,否则根据

onTouchEvent方法返回值决定dispatchTouchEvent返回值。

public void setOnClickListener(OnClickListener l) {        if (!isClickable()) {            setClickable(true);        }        mOnClickListener = l;    }

先判断当前View是否可点击的状态?如果不可点击的话,先设置成可点击,之后对

mOnClickListener赋值操作。总结:只要给任何一个View设置了setOnClickListener点击监听

事件,不管这个View是否是可点击的状态,最后都设置为了可点击的状态了。

2.只有当前View是可点击或者长按的状态,才进入if条件判断,然后执行相应的手势操作,最

后返回true。也就是说,只要View是可点击的,onTouchEvent方法返回的就是true,从而

dispatchTouchEvent方法返回的也是true。

3.只要是当前View是不可点击或者长按的状态,if条件不成立,不执行任何操作,直接返回

false。也就是说,View不可点击的时候,onTouchEvent方法返回的就是false,从而

dispatchTouchEvent方法返回的也是false。

4.onClick方法是在ACTION_UP手势里面执行的,也就是当手势抬起时才去执行onClick方法。

到此,Android View触摸事件传递已经分析结束。如果条件都满足,则整个触摸事件传递过程

就是:dispatchTouchEvent–>>onTouch–>>onTouchEvent–>>onClick。

当onTouch方法返回true时,就不执行onTouchEvnet方法,因此也就不执行onClick点击事

件。可以理解成此时onTouch把触摸事件已经消费掉了,也就不会继续往下传递触摸事件。所

以如果你不想自己的View执行onTouchEvent方法,你可以设置onTouch事件,且返回值为

true即可。

默认情况下除了Button,TextView少数控件外,其他大部分View控件默认都是不可点击的状

态,除非你设置了View#setClickable(true)或者View#setOnClickListener。现在我将

MainActivity中的button.setClickable(true);这一行代码去掉且不设置setOnClickListener事件。

不知道你发现木有?此处打印看出只执行了ACTION_DOWN手指操作,其他的手势操作呢?

没有执行,为什么呢?

情况是这样的:当onTouch方法返回false,则dispatchTouchEvent方法就会执行

onTouchEvent方法,但是由于View不可点击,所以onTouchEvent是不执行if条件体的,也就

是onTouchEvent方法返回false,从而导致dispatchTouchEvent方法返回false,由于

dispatchTouchEvent方法返回false,导致后面的手势操作ACTION_MOVE,ACTION_UP得不

到执行。

总结:如果我们将手势操作分为三个过程的话:ACTION_DOWN,ACTION_MOVE,ACTION_UP。只有当dispatchTouchEvent方法返回true时,系统才会执行对应过程后面的手势操作。

这里写图片描述

1、触摸事件传递顺序:dispatchTouchEvent–>>onTouch–>>onTouchEvent–>>onClick。

2、onTouch和onTouchEvent区别:两个方法先后在dispatchTouchEvent中调用,只有给

View设置了触摸事件View#setOnTouchListener才会执行onTouch方法;onTouch方法的返

回值决定是否执行onTouchEvent方法。

3、手势操作执行的顺序为ACTION_DOWN,ACTION_MOVE,ACTION_UP,只有

dispatchTouchEvent方法返回true值时后面的手势才会被执行。

4、onClick方法的调用是在onTouchEvent的ACTION_UP手势里面执行的,也就是当手势抬起

时,手势操作结束才会触发onClick方法的调用。

原文:http://blog.csdn.net/feiduclear_up/article/details/47356429

原创粉丝点击