View 事件分发机制

来源:互联网 发布:烟雾效果app软件 编辑:程序博客网 时间:2024/06/04 08:47
Touch事件分发中只有两个主角:ViewGroup和View, 

ViewGroup的相关事件有三个:dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent(继承了View)。

View的相关事件只有两个:dispatchTouchEvent、onTouchEvent。


Android 4.2.2源码  View 的事件分发机制


View.dispatchTouchEvent -> View.setOnTouchListener-> View.onTouchEvent (使用到了OnLongClickListener,onClickListener)


public boolean dispatchTouchEvent(MotionEvent event)方法内部处理过程:


(1) 判断方法 onFilterTouchEventForSecurity()返回值,其内部处理是: 如果窗口被遮蔽了就返回false,否则返回true


(2) 方法返回false,说明窗口被遮蔽了,整个dispatchTouchEvent返回false


(3) 方法返回true,说明窗口没有被遮蔽,则继续(4)


(4) 如果 mOnTouchListener不为空,且view的enable状态是可用,且mOnTouchListener的onTouch返回true,则整个 dispatchTouchEvent方法返回true


(5) 否则touch事件交给View的onTouchEvent方法处理:

View的public boolean onTouchEvent(MotionEvent event)方法内部处理过程

(1)  如果view的状态是DISABLED 则直接返回

(2)  否则继续判断mTouchDelegate(触摸代表)是否为空

(3)  如果mTouchDelegate(视图的点击区域(增大或者缩小可点击区域)) 不为空且mTouchDelegate.onTouchEvent返回true,则整个onTouchEvent方法返回true


(4)  否则继续以下的判断View的clickable或long_clickable,如果其中一个为true,则对MotionEvent进行分析处理: 

if (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE))
{
....
swtich(event.getAction())
{
case ACTION_MOVE:
//如果触摸点不在当前视图内(手指移出了视图区域),则移除还没有执行的长按与轻触检测
//移除按下状态,移除后刷新视图
break;

case ACTION_DOWN:
 //设置 mHasPerformedLongPress = false
 //500ms后执行PerformClick()->OnLongClickListener,
 //如果onLongClickListener的onLongClick(View v)返回true,则 mHasPerformedLongPress=true,否则mHasPerformedLongPress依然是false


 break;
case ACTION_UP:
 //当前是按下的状态,如果 mHasPerformedLongPress=false(长按事件没有发生OnLongClickListener为空或onLongClickListener返回false),
 则执行public boolean PerformClick()方法,此方法内处理:如果onClickListener不为空则执行onClickListener并返回true

 break;
case ACTION_CANCEL:
  break;
}
 return true;
}

注意点:

如果对一个View同时设置了OnLongClickListener和onClickListener,

那么 如果OnLongClickListener中的onClick方法返回false,则 onClickListener会被执行的,
        如果OnLongClickListener中的onClick方法返回true, 则 onClickListener不会被执行的。

0 0
原创粉丝点击