Android事件分发机制解析(一)

来源:互联网 发布:减肥饮品知乎 编辑:程序博客网 时间:2024/06/11 18:55

之前一直没有时间写东西,现在打算写一篇关于事件分发机制的文章.关于这类文章网上肯定有许多而且还比我 的好的,我只是尽我最大努力讲清楚,也让我重新梳理一下.

onTouch , onClick, onTouchEvent的关联和区别

  • onTouch方法
  myButton.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                Log.i(TAG, "onTouch" + event.getAction());                return false;            }        });

我们通常用法就是这样,通过event.getAction()方法来判断用户ACTION_DOWN, ACTION_UP, ACTION_MOVE操作.那和onTouchEvent()有什么区别呢?我们看下onTouchEvent()方法

 @Override    public boolean onTouchEvent(MotionEvent event) {        Log.i(TAG, "onTouchEvent" + event.getAction());        return true;    }

发现它也可以有event 也可以判断用户操作 ,那我们应该怎么用,用哪个呢? 在这我要再讲一个方法

   @Override    public boolean dispatchTouchEvent(MotionEvent event) {        Log.i(TAG, "dispatchTouchEvent" + event.getAction());        return super.dispatchTouchEvent(event);    }

这个方法有什么用呢? 是这样的,这个方法当我们对控件view进行触摸的时候都会首先调用这个方法,它起到一个分发触摸事件的作用.是这样吗?我们看下我打印的log就知道了

09-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent009-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: onTouch009-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: onTouchEvent009-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent209-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: onTouch209-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: onTouchEvent209-01 13:22:40.352 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent209-01 13:22:40.352 2985-2985/com.xu.startservice I/==========>: onTouch209-01 13:22:40.352 2985-2985/com.xu.startservice I/==========>: onTouchEvent209-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent109-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: onTouch109-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: onTouchEvent109-01 13:22:40.358 2985-2985/com.xu.startservice I/==========>: onClick

0代表Down 2代表Move 3代表UP
因为我点击按钮的时候手抖了一下,所以才会出现两个2… 但是我们通过log事件的顺序可以看出执行方法的顺序是:
dispatchTouchEvent=>onTouch=>onTouchEvent=>onClick
为什么呢? 我们来看下dispatchTouchEvent方法的源码,方法里代码很多我们只看有用的:

 ListenerInfo li = mListenerInfo;            if (li != null && li.mOnTouchListener != null                    && (mViewFlags & ENABLED_MASK) == ENABLED                    && li.mOnTouchListener.onTouch(this, event)) {                result = true;            }            if (!result && onTouchEvent(event)) {                result = true;            }

mOnTouchListener 这个是我们setOnTouchListener(new View.OnTouchListener() )传入的TouchListener. mViewFlags & ENABLED_MASK == ENABLED这个是描述button是否能够点击,
li.mOnTouchListener.onTouch(this, event)这个就是我们在onTouch()方法返回值.所以我们通过参数就可以看到,当li.mOnTouchListener.onTouch(this, event)返回true, 就不能执行onTouchEvent了就会变成这样

09-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent009-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: onTouch009-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent209-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: onTouch209-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent109-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: onTouch1

所以onTouch()方法的级别比onTouchEvent()高,它的返回值决定onTouchEvent()是否执行.

原创粉丝点击