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

xiaoxiao2021-02-28  56

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

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/==========>: dispatchTouchEvent0 09-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: onTouch0 09-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: onTouchEvent0 09-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent2 09-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: onTouch2 09-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: onTouchEvent2 09-01 13:22:40.352 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent2 09-01 13:22:40.352 2985-2985/com.xu.startservice I/==========>: onTouch2 09-01 13:22:40.352 2985-2985/com.xu.startservice I/==========>: onTouchEvent2 09-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent1 09-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: onTouch1 09-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: onTouchEvent1 09-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/==========>: dispatchTouchEvent0 09-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: onTouch0 09-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent2 09-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: onTouch2 09-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent1 09-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: onTouch1

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

转载请注明原文地址: https://www.6miu.com/read-76031.html

最新回复(0)