View、ViewGroup的点击事件处理过程

本文详细解析了Android中View和ViewGroup的触摸事件分发流程,包括dispatchTouchEvent、onInterceptTouchEvent及onTouchEvent等关键方法的作用及调用时机。

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

View :

1、先执行disPatchTouchEvent方法,在这个方法中先判断 mTouchListener是否为空,如果不为空的话就调用mTouchListener.onTouch()方法。

2、如果 mTouchListener.onTouch()方法返回true,那么disPatchTouchEvent方法直接返回true,不在向下执行。

3、如果 mTouchListener.onTouch()方法返回返回false ,那么 result == false,继续调用 onTouchEvent(),这样onTouchEvent就被执行了。

4、在onTouchEvent()中判断 onClickListener是否存在,如果存在就调用onClickListener的onClick(),这样我们注册进来的onClickListener就被执行了。

在view的onTouchEvent中click和longclick执行完成后返回了true(默认就返回true),同时把true返回给disPatchTouchEvent,事件消费掉了。

通过View的源码加以说明:

 

//源码分析:
public boolean dispatchTouchEvent(MotionEvent event) {
	...
        ...


	    //noinspection SimplifiableIfStatement
            ListenerInfo li = mListenerInfo;         // 这里面集合了所有注册过来的listener,包括clickListener,touchListener
            if (li != null && li.mOnTouchListener != null       // listener不为空
                    && (mViewFlags & ENABLED_MASK) == ENABLED   // view是可点击的状态
                    && li.mOnTouchListener.onTouch(this, event)) {   // 执行TouchListener.onTouch方法,并根据返回值进行判断
                result = true;
            }
		
	    
	    // 
            if (!result && onTouchEvent(event)) {      // 调用onTouchEvent,里面再执行onClick/onLongClick
                result = true;
            }

	reutrn result;

}

 

ViewGroup:

主要是三个方法: 

dispatchTouchEvent(MotionEvent event) // 这个方法一定会调用,同时返回结果受当前View的onTouchEvent和子View的disPatchTouchEvent影响。


onInterceptTouchEvent(MotionEvent event) // 这个方法在ViewGroup的dispatchTouchEvent()方法中调用,用于判断当前布局是否拦截点击事件,需要拦截之后直接调用onTouchEvent()


onTouchEvent(MotionEvent event)    // 在dispatchTouchEvent()方法中调用。如果这个方法在接收到action_down后返回的是false,那么说明他不处理,需要向上传递,由上层处理。上层的onTouchEvent接收到以后重复这样的判断。只有处理了action_down事件的那个view才会接收到down之后的move和up事件。

 

public boolean dispatchTouchEvent(MotionEvent event) {
	...
        ...

	// 先判断是否需要拦截
	if(onInterceptTouchEvent(event)){
		// 需要拦截就直接处理
		onTouchEvent(event)
	}else{
	   // 不拦截就再向下(子view)传递
	   child.disPatchTouchEvent(event);  // 这个传递过程符合view的事件处理过程
	}

	reutrn result;

}

注 :详细的传递过程看这里

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值