Android事件分发机制源码剖析(1)——Activity对点击事件的分发过程

点击事件用MotionEvent表示,当一个点击操作发生时,事件最先传递给当前的Activity,由Activity得dispatchTouchEvent来进行事件派发,具体的工作由Activity内部的Window来完成。Window会将事件传递给DecorView,DecorView一般就是当前页面的顶层容器(即setContentView所设置的View的父容器),通过Acitivty#getWindow().getDecorView()可以获得。Activity的dispatchTouchEvent源码如下:

Activity#dispatchTouchEvent

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

分析一下上面的代码,首先事件开始交给Acitivty所附属的Window进行分发,如果返回true,整个事件循环就结束了,返回false意味着事件没人处理,所有View的onTouchEvent都返回了false,那么Activity的onTouchEvent就会被调用。

接下来看Window是如何将事件传递给ViewGroup的。通过源码我们知道,Window是个抽象类,而Window的superDispatchTouchEvent方法也是个抽象方法,因此我们必须找到Window的实现类。

然后,我们很容易就会发现Window的实现类就是PhoneWindow,那么PhoneWindow是如何处理事件的呢?

PhoneWindow#superDispatchTouchEvent

public boolean superDispatchTouchEvent(MotionEvent ev){
    return mDecor.superDispatchTouchEvent(ev);
}

可以发现,PhoneWindow将事件直接传递给了DecorView,这个DecorView又是什么呢?

private final class DecorView extends FrameLayou implements RootViewSurfaceTaker

//This is the top-level view of window,containing the window decor.
private DecorView mDecor;

publiv final View getDecorView(){
    if(mDecor==null){
        installDecor();
    }
    return mDecor;
}

我们知道,通过((ViewGroup)getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0)这种方式就可以获取Activity所设置的View,这个mDecor显然就是getWindow().getDecorView()返回的View,而我们通过setContentView设置的View是它的一个子View。目前事件传递到了DecorView这里,由于DecorView继承自FrameLayout且是父View,所以最终事件就会传递给View。换句话说,事件肯定会传递到View,不然应用怎么响应点击事件呢?分析到这里,事件已经传递给顶级的View了,即在Activity中通过setContentView设置的View,另外顶层View也叫根View,顶层View一般来说都是ViewGroup。

至此,Activity对点击事件的分发过程已经介绍完毕,有关事件在ViewGroup和View中的传递过程请关注后面的博文。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值