android client端点击事件的派发流程

Android 的消息分发,可分为两部分,一部分是在服务器端的分发(在各种Service中),一部分是在Client端的分发(以ViewRoot为开始)。


本文只分析Client端点击消息的分发,其他的与此类似。


背景介绍。创建一个Activity,Activity上有一个水平方向的LinearLayout,这个Layout上放了一个ListView和一个GridView结构如图所示。ListView和GridView各Node都是继承TextView来进行简单显示。

Android <wbr>Client端点击消息分发路径.

想实现功能:GridView上按鼠标左键拖动时,能实时画出拖动的矩形。


实现原理:在GridView中重写onTouchEvent(MotionEvent event)方法,计算出矩形的位置,然后调用postInvalidate()进行绘制


问题:如果拖动先在Item以外的区域,则画矩形没有问题,如果拖动的开始是在Item上的话,则画矩形出现问题,简单调查后发现,在Item上点击拖动时,不会走到GridView的onTouchEvent方法,也就是说Item将事件截获,并进行了处理。同样在Item上的点击事件也不会走到GridView的onTouchEvent方法。


现在以GridView的点击为例,说明整个调用的过程。
1,ViewRoot 中先走到 handleMessage()这里会调用到mView.dispatchTouchEvent(event)。即是调用到mView的dispatchTouchEvent(),这个mView其实是PhoneWindow中的DecorView。


2,DecorView的dispatchTouchEvent(event)方法很简单,一般而言我们会走到 cb.dispatchTouchEvent(ev) 而cb 是Callback,这个Callback是什么呢?就是我们的Activity。


3,Activity的dispatchTouchEvent(ev)中有这么一句 getWindow().superDispatchTouchEvent(ev),这里的getWindow 返回的是PhoneWindow,而它的实现是mDecor.superDispatchTouchEvent(event)。


4,DecorView的superDispatchTouchEvent(event) 实现是super.dispatchTouchEvent(event);而这个调用走到了ViewGroup 的dispatchTouchEvent(MotionEvent ev);因为DecorView是继承的FrameLayout,所以其实调用的实现类是FrameLayout。


5,FrameLayout-ViewGroup()的dispatchTouchEvent(MotionEvent ev) 会查询它的子View,并调用子View 的dispatchTouchEvent(ev),在我们这个例子中,就是调用到了LinearLayout的dispatchTouchEvent(ev)。


6,LinearLayout-ViewGroup()的dispatchTouchEvent(MotionEvent ev)继续查询它的子View,并继续调用子View 的dispatchTouchEvent(ev),这时调用到了GridView的dispatchTouchEvent(ev),GridView此函数的实现也在ViewGroup()中。


7,GridView-ViewGroup()的dispatchTouchEvent(MotionEvent ev)终于把消息发送到了根结点的View TextView。TextView 的dispatchTouchEvent(MotionEvent ev)是由View来实现的。

 

8,TextView-View()的dispatchTouchEvent(MotionEvent ev),在这里TextView响应了点击事件,并返回了true;

 

返回true之后,我们第7步中有
    if (child.dispatchTouchEvent(ev))  {
      // Event handled, we have a target now.
      mMotionTarget = child;
      return true;
    }
    这样事件就结束了派发,所以我们GridView的onTouchEvent(MotionEvent event),就不会调用到了。

解决方法TextView 重写onTouchEvent 方法,返回false;将点击事件交给GridView来整体管理。

http://blog.sina.com.cn/s/blog_6e15a6010100mmg4.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值