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

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

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()是否执行.

猜你喜欢

转载自blog.csdn.net/xuhang1993/article/details/77771839
今日推荐