浅谈 View 的 OnTouchEvent 和 OnTouchListener 的区别

本文深入探讨了Android中View的OnTouchEvent和OnTouchListener的区别。OnTouchEvent是View直接处理MotionEvent的方法,而OnTouchListener是通过View的内部类ListenerInfo来管理的监听器,用于捕获触摸事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从源码来看,OnTouchEvent是View的一个方法,处理MotionEvent封装的事件,而OnTouchListener是View内部静态类ListenerInfo的一个实例变量,ListenerInfo封装了一个View各种事件监听器。如图:


当ACTION_DOWN事件传递给View时,此时先调用View的dispatchTouchEvent,我们看看dispatchTouchEvent 的源码


   /**
     * Pass the touch screen motion event down to the target view, or this
     * view if it is the target.
     *
     * @param event The motion event to be dispatched.
     * @return True if the event was handled by the view, false otherwise.
     */
    public boolean dispatchTouchEvent(MotionEvent event) {
        // If the event should be handled by accessibility focus first.
        if (event.isTargetAccessibilityFocus()) {
            // We don't have focus or no virtual descendant has it, do not handle the event.
            if (!isAccessibilityFocusedViewOrHost()) {
                return false;
            }
            // We have focus and got the event, then use normal event dispatch.
            event.setTargetAccessibilityFocus(false);
        }
		...


        boolean result = false;
		
		...
		
        if (onFilterTouchEventForSecurity(event)) {
            //noinspection SimplifiableIfStatement
            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;
    }

这里我们只看对于返回值有影响的方法,即代码中result值的变化。默认result为false,下面就是几个if语句,这里的mListenerInfo 就是ListenerInfo 的对象,View唯一的ListenerInfo 的实例,当用户设置setOnTouchListener监听器时,如下
   /**
     * Register a callback to be invoked when a touch event is sent to this view.
     * @param l the touch listener to attach to this view
     */
    public void setOnTouchListener(OnTouchListener l) {
        getListenerInfo().mOnTouchListener = l;
    }

getListenerInfo 就生成了mListenerInfo,这里就设置了mListenerInfo的一个成员变量mOnTouchListener 为 l 。回到if语句来,li.mOnTouchListener.onTouch(this, event) 这句话就在执行用户设置的setOnTouchListener的回调,它的结果返回true,消费此次事件,result = true 那么将不会执行下面 onTouchEvent(event)方法;如果它的结果返回false,那么继续执行onTouchEvent(event)方法。最终根据result值,如果dispatchTouchEvent返回true 代表 view消费了此事件,如果返回false就代表不做处理,这里的result值也传给了ViewGroup中负责子View之间转移事件的方法,遍历所有子View,得出在ViewGroup的onInterceptTouchEvent默认返回false 的前提下,它的dispatchTouchEvent方法返回值。

总结:用户不设置OnTouchListener,系统是默认执行onTouchEvent(event)方法,如果设置了OnTouchListener,那么就会先执行它,根据OnTouchListener的返回值再决定是否执行onTouchEvent(event)。看来OnTouchListener的优先级比onTouchEvent要高。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值