Android中onInterceptTouchEvent和dispatchTouchEvent的区别是什么?
根据android开发者指南,这两种方法都可以用来拦截触摸事件(MotionEvent),但有什么区别呢?
onInterceptTouchEvent, dispatchTouchEvent和onTouchEvent如何在视图(ViewGroup)的层次结构中一起交互?
Android中onInterceptTouchEvent和dispatchTouchEvent的区别是什么?
根据android开发者指南,这两种方法都可以用来拦截触摸事件(MotionEvent),但有什么区别呢?
onInterceptTouchEvent, dispatchTouchEvent和onTouchEvent如何在视图(ViewGroup)的层次结构中一起交互?
当前回答
我在http://doandroids.com/blogs/tag/codeexample/这个网页上看到了非常直观的解释。从这里开始:
boolean onTouchEvent(MotionEvent ev) -当检测到以该视图为目标的触摸事件时调用 boolean onInterceptTouchEvent(MotionEvent ev) -当一个触摸事件被检测到并以这个ViewGroup或它的子对象作为目标时调用。如果这个函数返回true, MotionEvent将被拦截,这意味着它不会被传递给子视图,而是传递给这个视图的onTouchEvent。
其他回答
简单回答:dispatchTouchEvent()将首先被调用。
简短的建议:不应该重写dispatchTouchEvent(),因为它很难控制,有时它会降低您的性能。恕我直言,我建议重写onInterceptTouchEvent()。
因为大多数答案都非常清楚地提到了活动/视图组/视图上的流触摸事件,我只添加了更多关于ViewGroup中这些方法的代码细节(忽略dispatchTouchEvent()):
onInterceptTouchEvent()将首先被调用,ACTION事件将分别被调用down -> move -> up。有2种情况:
If you return false in 3 cases (ACTION_DOWN, ACTION_MOVE, ACTION_UP), it will consider as the parent won't need this touch event, so onTouch() of the parents never calls, but onTouch() of the children will call instead; however please notice: The onInterceptTouchEvent() still continue to receive touch event, as long as its children don't call requestDisallowInterceptTouchEvent(true). If there are no children receiving that event (it can happen in 2 cases: no children at the position the users touch, or there are children but it returns false at ACTION_DOWN), the parents will send that event back to onTouch() of the parents. Vice versa, if you return true, the parent will steal this touch event immediately, and onInterceptTouchEvent() will stop immediately, instead onTouch() of the parents will be called as well as all onTouch() of children will receive the last action event - ACTION_CANCEL (thus, it means the parents stole touch event, and children cannot handle it from then on). The flow of onInterceptTouchEvent() return false is normal, but there is a little confusion with return true case, so I list it here: Return true at ACTION_DOWN, onTouch() of the parents will receive ACTION_DOWN again and following actions (ACTION_MOVE, ACTION_UP). Return true at ACTION_MOVE, onTouch() of the parents will receive next ACTION_MOVE (not the same ACTION_MOVE in onInterceptTouchEvent()) and following actions (ACTION_MOVE, ACTION_UP). Return true at ACTION_UP, onTouch() of the parents will NOT called at all since it's too late for the parents to steal touch event.
还有一件重要的事情是onTouch()中事件的ACTION_DOWN将决定视图是否希望从该事件接收更多的动作。如果视图在onTouch()中的ACTION_DOWN处返回true,这意味着视图愿意从该事件接收更多操作。否则,在onTouch()中的ACTION_DOWN处返回false将意味着视图不会从该事件接收更多的操作。
Activity和View都有dispatchTouchEvent()和onTouchEvent方法。ViewGroup也有这个方法,但是有另一个叫做onInterceptTouchEvent的方法。这些方法的返回类型是布尔型,您可以通过返回值控制调度路由。
Android中的事件调度从Activity->ViewGroup->View开始。
主要区别:
•Activity. dispatchtouchevent (MotionEvent) -这允许您的Activity 来拦截所有的触摸事件,然后再将它们分派到 窗口。 •ViewGroup.onInterceptTouchEvent(MotionEvent) -这允许一个 ViewGroup来监视事件,因为它们被分派到子视图。
我在http://doandroids.com/blogs/tag/codeexample/这个网页上看到了非常直观的解释。从这里开始:
boolean onTouchEvent(MotionEvent ev) -当检测到以该视图为目标的触摸事件时调用 boolean onInterceptTouchEvent(MotionEvent ev) -当一个触摸事件被检测到并以这个ViewGroup或它的子对象作为目标时调用。如果这个函数返回true, MotionEvent将被拦截,这意味着它不会被传递给子视图,而是传递给这个视图的onTouchEvent。
你可以在这个视频https://www.youtube.com/watch?v=SYoN-OvdZ3M&list=PLonJJ3BVjZW6CtAMbJz1XD8ELUs1KXaTD&index=19和接下来的三个视频中找到答案。所有的触摸事件都解释得很好,它非常清楚,充满了例子。