聊聊Android点击事件传递

简述

Android系统中,每个Activity的用户界面都是有View和ViewGroup对象来组成的。

那么当在界面上做了点击之后,点击事件是如何传递并处理的呢?
首先点击事件处理相关的有三个接口函数:

 
     
1
2
3
4
5
6
7
8
9
10
11
12
13
 
     
//分派事件
public boolean dispatchTouchEvent(MotionEvent ev)
//拦截事件,ViewGroup类中的源码实现就是{return false;}
表示不拦截该事件,事件将向下传递(传递给其子View);
若手动重写该方法,使其返回 true则表示拦截,事件将终止向下传递,
事件由当前ViewGroup类来处理,就是调用该类的 onTouchEvent ()方法
public boolean onInterceptTouchEvent (MotionEvent ev)
//处理事件,返回true则表示该View能处理该事件,事件将
终止向上传递(传递给其父View);返回 false表示不能处理,
则把事件传递给其父View的 onTouchEvent ()方法来处理
public boolean onTouchEvent (MotionEvent event)

只有ViewGroup才有onInterceptTouchEvent这个方法,可以向下拦截事件的传递。

示例

下面根据一个示例进行说明:TouchEventSample(代码地址)

红色区域为普通FragmentLayout
蓝色区域为MyRelativeLayout(继承自RelativeLayout,重写了上述三个方法,用于测试点击事件拦截和处理)
白色区域为MyTextView(重写了dispatchTouchEvent和onTouchEvent两个方法)
MainActivity,则重写了上述三个方法
点击右上角case1-case5,分别对应五种情况。

case1:

点击事件,均不拦截,MyTextView也不做处理。

 
     
1
2
3
4
5
6
7
8
9
10
11
 
     
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: onInterceptTouchEvent, MotionEvent.ACTION_DOWN
E/MyTextView: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyTextView: onTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: onTouchEvent, MotionEvent.ACTION_DOWN
E/MainActivity: onTouchEvent, MotionEvent.ACTION_DOWN
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: onTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_UP
E/MainActivity: onTouchEvent, MotionEvent.ACTION_UP


case2:

点击事件,均不拦截,MyTextView处理点击事件。

 
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
     
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: onInterceptTouchEvent, MotionEvent.ACTION_DOWN
E/MyTextView: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyTextView: onTouchEvent, MotionEvent.ACTION_DOWN
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_MOVE
E/MyRelativeLayout: dispatchTouchEvent, MotionEvent.ACTION_MOVE
E/MyRelativeLayout: onInterceptTouchEvent, MotionEvent.ACTION_MOVE
E/MyTextView: dispatchTouchEvent, MotionEvent.ACTION_MOVE
E/MyTextView: onTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: onTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_UP
E/MyRelativeLayout: dispatchTouchEvent, MotionEvent.ACTION_UP
E/MyRelativeLayout: onInterceptTouchEvent, MotionEvent.ACTION_UP
E/MyTextView: dispatchTouchEvent, MotionEvent.ACTION_UP
E/MyTextView: onTouchEvent, MotionEvent.ACTION_UP
E/MainActivity: onTouchEvent, MotionEvent.ACTION_UP


case3:

点击事件,MyRelativeLayout进行拦截,但不做处理。

 
     
1
2
3
4
5
6
7
8
9
10
11
 
     
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: onInterceptTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: onTouchEvent, MotionEvent.ACTION_DOWN
E/MainActivity: onTouchEvent, MotionEvent.ACTION_DOWN
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: onTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: onTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_UP
E/MainActivity: onTouchEvent, MotionEvent.ACTION_UP


case4:

点击事件,MyRelativeLayout进行拦截,并进行处理。

 
     
1
2
3
4
5
6
7
8
9
10
11
12
 
     
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: onInterceptTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: onTouchEvent, MotionEvent.ACTION_DOWN
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_MOVE
E/MyRelativeLayout: dispatchTouchEvent, MotionEvent.ACTION_MOVE
E/MyRelativeLayout: onTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: onTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_UP
E/MyRelativeLayout: dispatchTouchEvent, MotionEvent.ACTION_UP
E/MyRelativeLayout: onTouchEvent, MotionEvent.ACTION_UP
E/MainActivity: onTouchEvent, MotionEvent.ACTION_UP


case5:

点击事件,均不拦截,MainActivity处理点击事件。

 
     
1
2
3
4
5
6
7
8
9
10
11
 
     
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: onInterceptTouchEvent, MotionEvent.ACTION_DOWN
E/MyTextView: dispatchTouchEvent, MotionEvent.ACTION_DOWN
E/MyTextView: onTouchEvent, MotionEvent.ACTION_DOWN
E/MyRelativeLayout: onTouchEvent, MotionEvent.ACTION_DOWN
E/MainActivity: onTouchEvent, MotionEvent.ACTION_DOWN
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: onTouchEvent, MotionEvent.ACTION_MOVE
E/MainActivity: dispatchTouchEvent, MotionEvent.ACTION_UP
E/MainActivity: onTouchEvent, MotionEvent.ACTION_UP


参考文章:
Android-Developer-输入事件
Managing Touch Events in a ViewGroup

猜你喜欢

转载自blog.csdn.net/maoshengdev/article/details/78228358