Android的事件传递机制

**

一、当一个按钮的点击事件产生后,它的传递过程如下:Activity–>Window–>View

**

1、点击事件用MotionEvent来表示,当一个点击事件发生时事件最先传递给当前的Activity,由Activity的dispatchTouchEvent来进行事件的分发。
2、在Activity的dispatchTouchEvent中通过window对象(通过getwindow获得)将事件传递给当前窗口的顶层view,即DecorView
3、DecorView通过getWindow().getDecorView().findViewById(android.R.id.content))来获得,我们通过setContentView所设置的就是decorview的子ViewGroup。
4、DecorView通过superDispatchTouchEvent传递给顶层view,就是我们通过setContentView设置的viewgroup
5、viewgroup通过自己的dispatchTouchEvent继续进行事件的传递……

Activity的dispatchTouchEvent方法,调用window对象的superDispatchTouchEvent方法

   public boolean dispatchTouchEvent(MotionEvent ev) {
       if (ev.getAction() == MotionEvent.ACTION_DOWN) {
           onUserInteraction();
       }
       if (getWindow().superDispatchTouchEvent(ev)) {
           return true;
       }
       return onTouchEvent(ev);
   }

PhoneWindow的superDispatchTouchEvent方法,调用DecorView的superDispatchTouchEvent方法

    @Override
    public boolean superDispatchTouchEvent(MotionEvent event) {
        return mDecor.superDispatchTouchEvent(event);
    }

DecorView的superDispatchTouchEvent方法,调用super.dispatchTouchEvent方法,因为DecorView继承FrameLayout,所以super.dispatchTouchEven进入ViewGroup的dispatchTouchEvent方法,进而把事件从根viewgroup向下传递。

    public boolean superDispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
    }

**

二、事件从根Viewgroup向下传递的过程

**
1、主要是有三个方法来进行传递和处理的
(1)、public boolean dispatchTouchEvent(MotionEvent event)
// 事件分发,activity把事件传递给了viewgroup,viewgroup的dispatchTouchEvent方法会被调用,viewgroup把事件传递给了view,view的dispatchTouchEvent方法会被调用。

(2)、public boolean dispatchTouchEvent(MotionEvent event)
// 事件拦截,只有viewgroup有,view没有,如果事件被拦截了,就不会再向下传递了。
// 返回false表示不做拦截,事件将向下分发到子View的dispatchTouchEvent方法。

(3)、public boolean onTouchEvent(MotionEvent ev)
// 返回true表示事件被消费,本次的事件终止。返回false表示事件没有被消费,将调用父View的onTouchEvent方法

注:ViewGroup有onInterceptTouchEvent方法,view没有
三个方法的关系看这里

2、伪代码表示

public boolean dispatchTouchEvent(MotionEvent ev) {
	boolean consume = false;  //事件是否被消费
	if (onInterceptTouchEvent(ev)){  //调用onInterceptTouchEvent判断是否拦截事件
		consume = onTouchEvent(ev);  //如果拦截则调用自身的onTouchEvent方法
	}else{
		consume = child.dispatchTouchEvent(ev); //不拦截调用子View的dispatchTouchEvent方法
	}
	return consume;//返回值表示事件是否被消费true事件终止,false调用父View的onTouchEvent方法
}

3、图示表示
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值