博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Difference between onInterceptTouchEvent and dispatchTouchEvent?
阅读量:2358 次
发布时间:2019-05-10

本文共 4007 字,大约阅读时间需要 13 分钟。

这些天在解决工作中的一个问题时,对android分发事件的机制有了一些深入的了解,下面的解答也很有帮助。

The best place to demystify this is the source code. The docs are woefully inadequate about explaining this.

dispatchTouchEvent is actually defined on Activity, View and ViewGroup. Think of it as a controller which decides how to route the touch events.

For example, the simplest case is that of View.dispatchTouchEvent which will route the touch event to either OnTouchListener.onTouchEvent if its defined or to the extension method onTouchEvent.

For ViewGroup.dispatchTouchEvent things are way more complicated. It needs to figure out which one of its child views should get the event (by calling child.dispatchTouchEvent). This is basically a hit testing algorithm where you figure out which child view's bounding rectangle contains the touch point coordinates.

But before it can dispatch the event to the appropriate child view, the parent can spy and/or intercept the event all together. This is what onInterceptTouchEvent is there for. So it calls this method first before doing the hit testing and if the event was hijacked (by returning true from onInterceptTouchEvent) it sends a ACTION_CANCEL to the child views so they can abandon their touch event processing (from previous touch events) and from then onwards all touch events at the parent level are dispatched toonTouchListener.onTouch (if defined) or onTouchEvent(). Also in that case, onInterceptTouchEvent is never called again.

Would you even want to override [Activity|ViewGroup|View].dispatchTouchEvent? Unless you are doing some custom routing you probably should not.

The main extension methods are ViewGroup.onInterceptTouchEvent if you want to spy and/or intercept touch event at the parent level and View.onTouchListener/View.onTouchEvent for main event handling.

All in all its overly complicated design imo but android apis lean more towards flexibility than simplicity.、

Because this is the first result on Google. I want to share with you a great Talk by Dave Smith on and the slides are available . It gave me a good deep understanding about the Android Touch System:

How the Activity handles touch:

  • Activity.dispatchTouchEvent()
    • Always first to be called
    • Sends event to root view attached to Window
    • onTouchEvent()
      • Called if no views consume the event
      • Always last to be called

How the View handles touch:

  • View.dispatchTouchEvent()
    • Sends event to listener first, if exists
      • View.OnTouchListener.onTouch()
    • If not consumed, processes the touch itself
      • View.onTouchEvent()

How a ViewGroup handles touch:

  • ViewGroup.dispatchTouchEvent()
    • onInterceptTouchEvent()
      • Check if it should supersede children
      • Passes ACTION_CANCEL to active child
      • Return true once consumes all subsequent events
    • For each child view, in reverse order they were added
      • If touch is relevant (inside view), child.dispatchTouchEvent()
      • If not handled by previous, dispatch to next view
    • If no children handle event, listener gets a chance
      • OnTouchListener.onTouch()
    • If no listener, or not handled
      • onTouchEvent()
  • Intercepted events jump over child step

He also provides example code of custom touch on .

Answer: Basically the dispatchTouchEvent() is called on every View layer to determine if a View is interested in an ongoing gesture. In a ViewGroup the ViewGroup has the ability to steal the touch events in his dispatchTouchEvent()-method, before it would call dispatchTouchEvent()on the children. The ViewGroup would only stop the dispatching if the ViewGroup onInterceptTouchEvent()-method returns true. The difference is that dispatchTouchEvent()is dispatching MotionEvents and onInterceptTouchEvent tells if it should intercept (not dispatching the MotionEvent to children) or not (dispatching to children).

You could imagine the  doing more-or-less this (very simplified):

public boolean dispatchTouchEvent(MotionEvent ev) {
if(!onInterceptTouchEvent()){
for(View child : children){
return child.dispatchTouchEvent(ev); } } return super.dispatchTouchEvent(ev);}

原文 :

转载地址:http://xoitb.baihongyu.com/

你可能感兴趣的文章
lucene的中文分词器http://www.blogjava.net/dreamstone/archive/2007/06/22/125726.html
查看>>
ICTCLAS分词系统Java调用接口在Eclipse中的安装 http://blog.csdn.net/CloneIQ/archive/2006/07/20/945909.aspx
查看>>
在基于Struts构架的Java Web项目中加入ICTCLAS分词http://blog.csdn.net/CloneIQ/archive/2006/08/09/1043088.aspx
查看>>
QQ尾巴病毒的发送原理分析http://www.bitscn.com/hack/virus/200607/46309.html
查看>>
手把手教你把Vim改装成一个IDE编程环境(图文)http://blog.csdn.net/wooin/archive/2007/10/31/1858917.aspx
查看>>
Skydrive 微软1G免费网盘申请
查看>>
什么是SEO http://www.seozone.net/search-engine-optimization/what-is-seo.html
查看>>
Closure http://www.martinfowler.com/bliki/Closure.html
查看>>
闭包(Closures)在各种语言中的例子 http://blog.csdn.net/ruby_cn/archive/2004/11/23/192588.aspx
查看>>
学做网页Applet录音机
查看>>
弹出run a dll as an app对话框&关机蓝屏的解决方法
查看>>
时空不是连续的
查看>>
勾股定理证明评监
查看>>
评测主流网站统计系统
查看>>
Jxta 命令 shell
查看>>
火页的窝--如何配置JXTA Shell(airclh)
查看>>
澳洲数学高手提速网络
查看>>
[图]跳过Windows,Phoenix开发内建在BIOS的小型操作系统
查看>>
奇技淫巧之避免因宏带来的名字冲突
查看>>
调试dll和exe加载失败
查看>>