安卓OnTouchListener,onTouchEvent,onClickListener执行顺序

原创 2017年08月03日 20:08:00

安卓控件有很多监听事件,比较典型的有OnTouchListener,onTouchEvent和mOnClickListener,来看下他们的执行顺序
我们先自定义一个Button,在他的onTouchEvent方法中加入log

@Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("xw", "onTouchEvent");
        return super.onTouchEvent(event);
    }

放进布局后在Activity中设置回调

bt1.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.e("xw", "OnTouchListener");
                return false;
            }
        });

bt1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("xw", "OnClickListener");
            }
        });

之后单击下,log信息为
这里写图片描述

可见是首先执行OnTouchListener,之后为onTouchEvent,最后才执行onClickListener内的方法,至于为什么OnTouchListener和onTouchEvent执行了两次,是因为在DOWN和UP时两个方法都被调用,至于onClickListener则只在UP的时候调用

我们看下安卓是怎么实现的

与事件分发相关联的三个方法分别为dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent,直接去看View的dispatchTouchEvent方法

public boolean dispatchTouchEvent(MotionEvent event) {
        ......
        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;
        }
        ......
        return result;
    }

我们先看ListenerInfo ,他是View的一个内部静态类

 static class ListenerInfo {

        protected OnFocusChangeListener mOnFocusChangeListener;
        private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;
        protected OnScrollChangeListener mOnScrollChangeListener;
        private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;
        public OnClickListener mOnClickListener;
        protected OnLongClickListener mOnLongClickListener;
        protected OnContextClickListener mOnContextClickListener;
        protected OnCreateContextMenuListener mOnCreateContextMenuListener;
        ......

    }

里面存储着View的各个Listener,我们之前设置的OnTouchListener也在其中

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

ListenerInfo getListenerInfo() {
        if (mListenerInfo != null) {
            return mListenerInfo;
        }
        mListenerInfo = new ListenerInfo();
        return mListenerInfo;
    }

其他的像onClickListener也是这样存储

回来我们接着看dispatchTouchEvent方法,从上面我们可以知道如果有的话OnTouchListener是比onTouchEvent先执行的,当然前提是OnTouchListener返回false,即OnTouchListener并没有处理事件

接着调用onTouchEvent方法

public boolean onTouchEvent(MotionEvent event) {
        ......
        switch (action) {
             case MotionEvent.ACTION_UP:
                  ......
                  performClick();
                  ......
                  break;
        ......
    }

public boolean performClick() {
        final boolean result;
        final ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            li.mOnClickListener.onClick(this);
            result = true;
        } else {
            result = false;
        }
        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
        return result;
    }

在View的onTouchEvent方法中,如果判断事件为MotionEvent.ACTION_UP时,则会调用performClick,而在performClick中则会回调mOnClickListener的onClick方法,即点击事件被回调,同时直接返回true

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android View的onTouchEvent和OnTouch区别

还是以自定义的TestButton为例。 我们可以通过重写onTouchEvent方法来处理诸如down move up的消息: public class TestButton extends...

[Android] 触屏setOnTouchListener实现图片缩放、移动、绘制和添加水印

本文主要讲述使用触屏实现图片缩放、移动、添加水印等功能,所以该篇文章主要通过setOnTouchListener监听实现该功能,如何使用RelativeLayout进行布局,MotionEvent.A...

Android中onTouch与onClick两种监听的完全解析

之前项目中做一个竖直方向的ViewPager效果(详见我的另一篇博文),这几天做了几个改动,突然发现我设置的OnTouchListener对触摸事件的监听突然不起作用了,琢磨了半天觉得问题就出在onT...

Android 事件分发 OnClickListener 和 OnTouchListener 的事件处理原理简单描述

在这次的实验练习中,我们只采用了一个 Button 去

Android onTouchEvent, onClick及onLongClick的调用机制

      针对屏幕上的一个View控件,Android如何区分应当触发onTouchEvent,还是onClick,亦或是onLongClick事件?在Android中,一次用户操作可以被不同的Vi...
  • ddna
  • ddna
  • 2010年04月05日 14:23
  • 55251

论onclicklistener、ontouchlistener、ontouchevent

本人新人写点自己的心得和

安卓onTouchEvent上下左右滑动事件

  • 2014年10月23日 15:31
  • 1.4MB
  • 下载

android应用中常用的监听OnTouchListener、OnClickListener、OnLongClickListener

android应用中常用的监听OnTouchListener、OnClickListener、OnLongClickListener,大家肯定经常使用。但是你真的知道它会产生的神奇效果么?不要忽视这些...

浅谈OnTouchListener,OnClickListener和OnLongClickListener的关系

初学Android,发现如题的这几个关系有点乱,经过查资料和自己做了个小测试,把这几个关系弄清楚了,发出来与大家分享。 先贴上本人小测试的代码: [java] view ...

你真的会用OnTouchListener、OnClickListener、OnLongClickListener监听事件么?

android应用中常用的监听OnTouchListener、OnClickListener、OnLongClickListener,大家肯定经常使用。但是你真的知道它会产生的神奇效果么?不要忽视这些...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:安卓OnTouchListener,onTouchEvent,onClickListener执行顺序
举报原因:
原因补充:

(最多只允许输入30个字)