View的事件体系(二)
来源:互联网 发布:68什么意思网络用语 编辑:程序博客网 时间:2024/06/05 23:44
一.事件由activity开始传递,activity的dispatchTouchEvent代码如下:
public boolean dispatchTouchEvent(MotionEvent ev){if(ev.getAction() == MotionEvent.Action_Down){onUserInteraction();
}if(getWindow().superDispatchTouchEvent(ev){return true;}return onTouchEvent(ev);}由于上面的代码我们可以知道,会直接调用window的superDispatchTouchEvent方法,当该方法返回false的时候,才会调用activity的onTouchEvent方法进行处理
window的实现类是PhoneWindow,实现方法如下:
public boolean superDispatchTouchEvent(MotionEvent event){return mDecor.superDispatchTouchEvent(event);}由上代码可知,直接调用了DecorView的superDispatchTouchEvent方法,点击事件由此进入view体系进行分发。
二.在ViewGroup的dispatchTouchEvent方法中:
final boolean intercepted;if(actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null){final boolean disallowIntercept = ( mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;if(!disallowIntercept){intercepted = onInterceptTouchEvent(ev);ev.setAction(action);}else{intercepted = false;}}else{intercepted = true;}
如果action_down事件由ViewGroup的子元素消耗,则mFirstTouchTarget != null
所以当mFirstTouchTarget == null时,表示ViewGroup的子元素不消耗action_down事件
这时action_move,action_up事件都会返回intercepted = true ,即该事件由ViewGroup处理
如果为action_down事件或者mFirstTouchTarget!= null 时,
会判读FLAG_DISALLOW_INTERCEPT标志是否为0,FLAG_DISALLOW_INTERCEPT由子view的requestDisallowInterTouchEvent方法设置,当设置为true时才
intercepted = false,ViewGroup将无法拦截事件
但如果事件为action_down,FLAG_DISALLOW_INTERCEPT会被重置,一定会调用onInterceptTouchEvent方法判断是否进行拦截
三.交给view处理
如果intercepted = false,表示viewGroup不拦截事件,将交给子view进行处理
他会遍历所有的子元素,
判断子元素是否在播动画已经点击事件是否落在子元素里,如果满足该条件,那么事件就传给他处理。
他会调用子元素的dispatchTouchEvent方法,
如果子元素的dispatchTouchEvent返回true,那么mFirstTouchTarget就会被赋值并终止对子view的遍历。
newTouchTarget = addTouchTarget(child,idBitsToAssign);alreadyDispatchedToNewTouchTarget = true;break;
private TouchTarget addTouchTarget(View child,int pointerIdBits){
TouchTarget target = TouchTarget.obtain(child,pointerIdBits);
target.next = mFirstTouchTarget;
mFirstTouchTarget = target;
return target;
如果返回false,则会将事件分发给下一个子元素。
如果ViewGroup没有 子元素,或者子元素处理了点击事件但它的dispatchTouchEvent返回false
ViewGroup会自己处理点击事件
if(mFirstTouchTarget == null){handled = dispatchTransformedTouchEvent(ev,canceled,null,TouchTarget.ALL_POINTER_IDS);}
四。View对点击事件的处理
public boolean dispatchTouchEvent(MotionEvent event){...if(onFilterTouchEventForSecurity(event){ListenterInfor 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;}}...return result;}}如果设置了mOnTouchListener,就会调用onTouch方法
如果没设置mOnTouchListener方法或者onTouch方法返回false才会调用onTouchEvent方法
当View处于不可用状态时,如果clickable或者long_clickable为true,也会消耗点击事件
if((viewFlags &ENABLED_MASK)==DISABLED){ if(event.getAction()== MotionEvent.ACTION_UP &&(mPrivateFlags &PFLAG_PRESSED)!= 0){setPressed(false);}return (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONE_CLICKABLE));}当发生ACTION_UP时会触发performClick方法,如果View设置了OnClickListener,那么performClick方法内部就会调用onClick方法
view的LONG_CLICKABLE属性默认为false,而CLICKABLE属性默认则由具体的控件决定,如TextView为false
setOnClickListener 或setOnLongClickListener方法会将相应的属性设置为true.
参考:Android开发艺术探索
- 读书笔记--View的事件体系(二)
- View的事件体系(二)
- View的事件体系(二)
- View事件体系(二)
- 《View的事件体系》(二)View的滑动实现
- View事件体系(二)View的滑动
- Android——View的事件体系(二)View的事件分发机制
- View详解之二View的事件体系
- View的事件体系
- View 的事件体系
- View的事件体系
- View的事件体系
- View的事件体系
- View的事件体系
- View的事件体系
- View的事件体系
- View的事件体系
- View的事件体系
- Linux搭建负载均衡集群,使用LVS的DR模式
- Ubuntu16.04下安装MySQL5.x的简单方法
- linux软连接和硬链接
- TEXT、TINYTEXT、MEDIUMTEXT、LONGTEXT选择 和 char varchar varchar2 的区别
- 1043. 输出PATest(20)
- View的事件体系(二)
- 阿里巴巴工程师:这些面试“套路”才能让你收获offer!
- eclipse连接mysql数据库
- 2017,我的不归年
- java通过输入工作日数(正或负)得到具体日期或计算两个日期之间的工作日
- <jsp:include>和<%@include%>的区别,JSP动态include和静态include的区别
- Android——实现光点模糊渐变的自旋转圆环特效
- 定时任务——Android之Alarm机制讲解
- Android 如何保存某个布局为图片