我们都知道自定义 View 的操作步骤是 measure,layout,draw,不过除此之外对自定义控件的响应事件也是非常重要的,即对 touchEvent 的响应,在进行自定义 View 时我们通常需要重写onMeasure(),onLayout(),onTouchEvent() 等方法,当然了,我们都知道自定义最难的地方在于 draw(即画)的过程,需要理解原理才有助于深入学习,有些难以理解,不过今天这一篇文章要说的不是 draw,而是 onTouchEvent( )方法。我们都知道,自定义 View 的第一步是测量当前剩余空间,或者说是界面的大小,也就是 measure 了;然后是 layout,即判断自定义 view 在父控件上显示的位置,这两点在上一篇通过讲解过了,所以今天我们要说的就是对 TouchEvent 的处理。
我们假设,一个 View 接收到了 Touch 事件,它会把这个事件传递给谁呢?
答案是 dispatchTouchEvent() 方法,所以我们就从这个方法入手
android.view.View.dispatchTouchEvent()
老规矩了,看一下 Google 官方文档对 dispatchTouchEvent() 这个方法的描述吧:
Pass the touch screen motion event down to the target view, or this view if it is the target.
将触摸屏运动事件向下传递到目标视图,如果它是目标,则视图。
嗯,这个方法是用于将触摸事件传递到目标并视图的,那么现在一起来看一下它的源码吧:
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.isTargetAccessibilityFocus()) {
if (!isAccessibilityFocusedViewOrHost()) {
return false;
}
event.setTargetAccessibilityFocus(false);
}
boolean result = false;
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
}
final int actionMasked = event.getActionMasked();
if (actionMasked == MotionEvent.ACTION_DOWN) {
stopNestedScroll();
}
if (onFilterTouchEventForSecurity(event)) {
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null &&
(mViewFlags&ENABLED_MASK)==ENABLED && li.mOnTouchListener.onTouch(this,event)) {
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
}
if (!result && mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
}
if (actionM