现在的位置: 首页 > 综合 > 正文

Android TouchEvent的传递

2018年01月29日 ⁄ 综合 ⁄ 共 8899字 ⁄ 字号 评论关闭

今天做了一些关于Android Touch时间的传递机制的研究,研究的结果是:

1. 点击事件是可以穿透View的;如果置于表层的View没有处理该事件,则被覆盖的View是可以接收到这个事件的。因为,屏幕上我们所创建的View,都是屏幕的根容器的Child。而ViewGroup在dispatchTouchEvent时,会将事件依次传递给各个Child。

2. 可以发现,dispatchTouchEvent这个函数是一个类似于递归调用的函数。其流程是:

如果 

1. View不为ViewGroup

2. View为ViewGroup,但是没有Child

2. View截获了这个事件,即在onInterceptTouchEvent中返回了True

则:将TouchEvent传递给onTouchEvent进行处理,然后dispatchTouchEvent结束。

否则:View遍历并调用所有的Child的dispatchTouchEvent

3. 如果某个子View在Down时返回了True,则代表:我关心这个Touch系列时间;因此,如果上层没有intercept事件,以后的Move、Up等时间,都会传递给该View;就算该View在其他的Move事件中返回了false,接下来的事件依旧会传递到这个View中。

4. 如果子View在onTouchEvent中返回了True,则父类的onTouchEvent是接收不到TouchEvent的,除非调用onInterceptTouchEvent。

5. 如果整个链条中都没有人在onTouchEvent中返回True,则之后的一系列事件,不会再传递给这个ViewGroup了。

下面是我的测试代码和测试输出,有兴趣可以看一下。

以下是View的层次结构:

MyLinearLayout派生自Linearlayout,只是在三个关于TouchEvent传递的函数dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent中输出了当前的状态。

	public View getMyView()
	{
		MyLinearLayout root = new MyLinearLayout(this);
		MyLinearLayout layout = root;
		for (int i=0; i<5; i++)
		{
			MyLinearLayout view = new MyLinearLayout(this);
			layout.addView(view, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
			layout = view;
		}
		
		return root;
	}

1. 所有的onInterceptTouchEvent和onTouchEvent都没有做任何处理;即都返回false

E/Touch Test(18929): Level 0: dispatchTouchEvent begin::Down
E/Touch Test(18929): Level 0: onInterceptTouchEvent:Down: return false
E/Touch Test(18929): —— Level 1: dispatchTouchEvent begin::Down
E/Touch Test(18929): —— Level 1: onInterceptTouchEvent:Down: return false
E/Touch Test(18929): —— —— Level 2: dispatchTouchEvent begin::Down
E/Touch Test(18929): —— —— Level 2: onInterceptTouchEvent:Down: return false
E/Touch Test(18929): —— —— —— Level 3: dispatchTouchEvent begin::Down
E/Touch Test(18929): —— —— —— Level 3: onInterceptTouchEvent:Down: return false
E/Touch Test(18929): —— —— —— —— Level 4: dispatchTouchEvent begin::Down
E/Touch Test(18929): —— —— —— —— Level 4: onInterceptTouchEvent:Down: return false
E/Touch Test(18929): —— —— —— —— Level 4: onTouchEvent:Down: return false
E/Touch Test(18929): —— —— —— —— Level 4: dispatchTouchEvent end::Down: return false
E/Touch Test(18929): —— —— —— Level 3: onTouchEvent:Down: return false
E/Touch Test(18929): —— —— —— Level 3: dispatchTouchEvent end::Down: return false
E/Touch Test(18929): —— —— Level 2: onTouchEvent:Down: return false
E/Touch Test(18929): —— —— Level 2: dispatchTouchEvent end::Down: return false
E/Touch Test(18929): —— Level 1: onTouchEvent:Down: return false
E/Touch Test(18929): —— Level 1: dispatchTouchEvent end::Down: return false
E/Touch Test(18929): Level 0: onTouchEvent:Down: return false
E/Touch Test(18929): Level 0: dispatchTouchEvent end::Down: return false

2. Level 3,onInterceptTouchEvent返true,其他的onInterceptTouchEvent返回false;

所有的onTouchEvent返回false

E/Touch Test(27070): Level 0: dispatchTouchEvent begin::Down
E/Touch Test(27070): Level 0: onInterceptTouchEvent:Down: return false
E/Touch Test(27070): —— Level 1: dispatchTouchEvent begin::Down
E/Touch Test(27070): —— Level 1: onInterceptTouchEvent:Down: return false
E/Touch Test(27070): —— —— Level 2: dispatchTouchEvent begin::Down
E/Touch Test(27070): —— —— Level 2: onInterceptTouchEvent:Down: return false
E/Touch Test(27070): —— —— —— Level 3: dispatchTouchEvent begin::Down
E/Touch Test(27070): —— —— —— Level 3: onInterceptTouchEvent:Down: return true
E/Touch Test(27070): —— —— —— Level 3: onTouchEvent:Down: return false
E/Touch Test(27070): —— —— —— Level 3: dispatchTouchEvent end::Down: return false
E/Touch Test(27070): —— —— Level 2: onTouchEvent:Down: return false
E/Touch Test(27070): —— —— Level 2: dispatchTouchEvent end::Down: return false
E/Touch Test(27070): —— Level 1: onTouchEvent:Down: return false
E/Touch Test(27070): —— Level 1: dispatchTouchEvent end::Down: return false
E/Touch Test(27070): Level 0: onTouchEvent:Down: return false
E/Touch Test(27070): Level 0: dispatchTouchEvent end::Down: return false

3. onInterceptTouchEvent都返回false;
在Level 3中onTouchEvent返回true;其他的onTouchEvent都返回false。

E/Touch Test(21314): Level 0: dispatchTouchEvent begin::Down
E/Touch Test(21314): Level 0: onInterceptTouchEvent:Down: return false
E/Touch Test(21314): —— Level 1: dispatchTouchEvent begin::Down
E/Touch Test(21314): —— Level 1: onInterceptTouchEvent:Down: return false
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent begin::Down
E/Touch Test(21314): —— —— Level 2: onInterceptTouchEvent:Down: return false
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent begin::Down
E/Touch Test(21314): —— —— —— Level 3: onInterceptTouchEvent:Down: return false
E/Touch Test(21314): —— —— —— —— Level 4: dispatchTouchEvent begin::Down
E/Touch Test(21314): —— —— —— —— Level 4: onInterceptTouchEvent:Down: return false
E/Touch Test(21314): —— —— —— —— Level 4: onTouchEvent:Down: return false
E/Touch Test(21314): —— —— —— —— Level 4: dispatchTouchEvent end::Down: return false
E/Touch Test(21314): —— —— —— Level 3: onTouchEvent:Down: return true
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent end::Down: return true
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent end::Down: return true
E/Touch Test(21314): —— Level 1: dispatchTouchEvent end::Down: return true
E/Touch Test(21314): Level 0: dispatchTouchEvent end::Down: return true

E/Touch Test(21314): Level 0: dispatchTouchEvent begin::Move
E/Touch Test(21314): Level 0: onInterceptTouchEvent:Move: return false
E/Touch Test(21314): —— Level 1: dispatchTouchEvent begin::Move
E/Touch Test(21314): —— Level 1: onInterceptTouchEvent:Move: return false
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent begin::Move
E/Touch Test(21314): —— —— Level 2: onInterceptTouchEvent:Move: return false
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent begin::Move
E/Touch Test(21314): —— —— —— Level 3: onTouchEvent:Move: return true
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent end::Move: return true
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent end::Move: return true
E/Touch Test(21314): —— Level 1: dispatchTouchEvent end::Move: return true
E/Touch Test(21314): Level 0: dispatchTouchEvent end::Move: return true

E/Touch Test(21314): Level 0: dispatchTouchEvent begin::Up
E/Touch Test(21314): Level 0: onInterceptTouchEvent:Up: return false
E/Touch Test(21314): —— Level 1: dispatchTouchEvent begin::Up
E/Touch Test(21314): —— Level 1: onInterceptTouchEvent:Up: return false
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent begin::Up
E/Touch Test(21314): —— —— Level 2: onInterceptTouchEvent:Up: return false
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent begin::Up
E/Touch Test(21314): —— —— —— Level 3: onTouchEvent:Up: return true
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent end::Up: return true
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent end::Up: return true
E/Touch Test(21314): —— Level 1: dispatchTouchEvent end::Up: return true
E/Touch Test(21314): Level 0: dispatchTouchEvent end::Up: return true

4. onInterceptTouchEvent都返回false;

在Level 3中onTouchEvent中,如果event为Down,则true;否则返回false;
其他的onTouchEvent都返回false。

E/Touch Test(3245): Level 0: dispatchTouchEvent begin::Down
E/Touch Test(3245): Level 0: onInterceptTouchEvent:Down: return false
E/Touch Test(3245): —— Level 1: dispatchTouchEvent begin::Down
E/Touch Test(3245): —— Level 1: onInterceptTouchEvent:Down: return false
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent begin::Down
E/Touch Test(3245): —— —— Level 2: onInterceptTouchEvent:Down: return false
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent begin::Down
E/Touch Test(3245): —— —— —— Level 3: onInterceptTouchEvent:Down: return false
E/Touch Test(3245): —— —— —— —— Level 4: dispatchTouchEvent begin::Down
E/Touch Test(3245): —— —— —— —— Level 4: onInterceptTouchEvent:Down: return false
E/Touch Test(3245): —— —— —— —— Level 4: onTouchEvent:Down: return false
E/Touch Test(3245): —— —— —— —— Level 4: dispatchTouchEvent end::Down: return false
E/Touch Test(3245): —— —— —— Level 3: onTouchEvent:Down: return true
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent end::Down: return true
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent end::Down: return true
E/Touch Test(3245): —— Level 1: dispatchTouchEvent end::Down: return true
E/Touch Test(3245): Level 0: dispatchTouchEvent end::Down: return true

E/Touch Test(3245): Level 0: dispatchTouchEvent begin::Move
E/Touch Test(3245): Level 0: onInterceptTouchEvent:Move: return false
E/Touch Test(3245): —— Level 1: dispatchTouchEvent begin::Move
E/Touch Test(3245): —— Level 1: onInterceptTouchEvent:Move: return false
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent begin::Move
E/Touch Test(3245): —— —— Level 2: onInterceptTouchEvent:Move: return false
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent begin::Move
E/Touch Test(3245): —— —— —— Level 3: onTouchEvent:Move: return false
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent end::Move: return false
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent end::Move: return false
E/Touch Test(3245): —— Level 1: dispatchTouchEvent end::Move: return false
E/Touch Test(3245): Level 0: dispatchTouchEvent end::Move: return false

E/Touch Test(3245): Level 0: dispatchTouchEvent begin::Up
E/Touch Test(3245): Level 0: onInterceptTouchEvent:Up: return false
E/Touch Test(3245): —— Level 1: dispatchTouchEvent begin::Up
E/Touch Test(3245): —— Level 1: onInterceptTouchEvent:Up: return false
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent begin::Up
E/Touch Test(3245): —— —— Level 2: onInterceptTouchEvent:Up: return false
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent begin::Up
E/Touch Test(3245): —— —— —— Level 3: onTouchEvent:Up: return false
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent end::Up: return false
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent end::Up: return false
E/Touch Test(3245): —— Level 1: dispatchTouchEvent end::Up: return false
E/Touch Test(3245): Level 0: dispatchTouchEvent end::Up: return false

抱歉!评论已关闭.