View的三种事件触发方式
1、dispatchTouchEvent(MotionEvent
ev) 事件分发
2、onInterceptTouchEvent(MotionEvent
ev) 事件拦截
3、onTouchEvent(MotionEvent
event) 事件响应
其中的事件拦截onInterceptTouchEvent 只有ViewGroup中存在
activity:
自定义ViewGroup:
自定义View:
xml:
分发
拦截
响应
activity 默认(false) 默认
ViewGroup 默认 默认 默认
View默认 默认 默认
首先通过activity分发---->ViewGroup分发---->ViewGroup拦截---->View分发
activity响应
当都为默认值时的执行顺序
ViewGroup与View均不响应事件时,则activity响应,当下次再次有事件activity不会向下分发而是自己响应
分发
拦截
响应
activity 默认(false) 默认
ViewGroup true 默认 默认
View默认 默认 默认
activity的分发为true时
ViewGroup的分发为true
View的分发为true时
当分发的返回值为true时,代表当前View的分发消耗了事件,则就向下一级发出事件
ViewGroup的拦截为true
当ViewGroup的拦截为true时,也不会向下一级(View)发出事件,与分发不同的是,拦截不会消耗时间,转而发给响应事件
当响应事件为true时
activity的响应为true
ViewGroup的响应为true
View的响应为true
当响应时间为true时不会影响事件的向下分发,但是在往回(View--activity)调用响应事件时,当返回值为true则消耗了事件,便不会再往上一级发事件
源码中的逻辑
1.enabled =false之后,我们是不是就接收不到事件了?
能够拿到事件,但是监听没有触发
可以看出enabled 的值只是在事件中做一个逻辑判断,并不影响事件的执行
2.enabled =false之后,为什么监听,选择器就失效了?
3.为什么只有clickble=true,选择器才生效
2,3的原因如下:
在onTouchEvent中有一下代码,当enable=false时,直接return,不会往下执行。只有为true时才会执行下列代码
4.为什么setOnClickListener之后,我们即使不设置clickble=true,选择器也生效
原因在于当调用onClickListener方法时,会将cliclkable设置成true
并将监听赋值给ListenerInfo中
5.为什么dispatchTouchEvent会优先于onTouchEvent和onInterceptTouchEvent执行
原因在于在View源码的dispatchTouchEvent()方法中有以下代码
可以看出onTouchEvent方法是在dispatchTouchEvent方法的内部执行的
1、其中的result指的是当前dispatchTouchEvent()的返回值,当dispatchTouchEvent()的返回值为true在最后一个if中的‘半路与’操作中!result = false,就不会调用后面的onTouchEvent(),从以上代码可以看出,当满足了内部的第一个if中的条件result才会变成true从而也不会执行onTouchEvent()
2、当我们的返回值为true时,不调用父类的dispatchTouchEvent()方法(上面展示的View的dispatchTouchEvent()方法),所以不会调用到父类中dispatchTouchEvent()的onTouchEvent()了
所以dispatchTouchEvent为true时onTouchEvent不会执行
但是当手动调用父类的dispatchTouchEvent时,无论当前控件的dispatchTouchEvent()的返回值是否为true,均会调用到当前空间的onTouchEvent
6.为什么OnTouchListener会优先于OnClickListener执行,为什么OnTouchListener retrun true,OnClickListener就不执行了
同5:OnClickListener方法在OnTouchListener中执行,在OnTouchListener中执行onTouch()方法,当onTouch()返回值为true时result为true,由下面的if ’短路与‘操作!result=false,所以不会执行到onTouchEvent()方法。然而在onTouchEvent()方法中有一下代码:
performClick():
可以看出在onClick()在onTouchEvent()中执行
综上所述
OnTouchListener return
true时,dispatchTouchEvent中的result为true,当result为true时,短路与的if不会执行onTouchEvent()方法,所以更不会执行onTouchEvent()中的onClick()方法
7.ListenerInfo(一种思想)
当前控件所有监听的封装,同一管理
作用在于当控件使用到某些监听时,把这些监听全部赋值给ListenerInfo中的监听变量,这样,当我们需要覆写好的监听时,只需要在ListenerInfo中获取就行了
8.performClick....
自定义View属性
1、在资源文件中定义属性
2、在View中调用
自定义的属性需要自定义的前缀
“xx:”默认为“app:”,无论什么前缀都需要引入文件
xmlns:xx="http://schemas.android.com/apk/res-auto"
代表该前缀修饰的属性自动在res文件下寻找。
3、在java中编写属性的逻辑
①、在什么view用,就要继承什么view
②、获取该view中所有属性集合
在TypedArray后调用recycle主要是为了缓存。当recycle被调用后,这就说明这个对象从现在可以被重用了。TypedArray
内部持有部分数组,它们缓存在Resources类中的静态字段中,这样就不用每次使用前都需要。
③、编写逻辑
repeatNum(attrs):
textOrientation(attrs):
关于善知教育(官网:www.itszt.com微信公众号:善知技术)
地址:北京东燕郊经济技术开发区文化大厦
咨询老师郑老师电话微信13315631002QQ1939441377
目前我们开设Java服务器Html5前端网页Android移动端PHP服务器,有全日制班有周末班,学费优惠至8480,我们的优势:基础课程一个月免费学全程面授,平均就业薪资10000-15000,免费重听,跨学科免费学习
5-5.5个月大容量技术授课
0学费0基础入学,海量项目实训,弹性教学制度,大部分学生找到月薪10k以上薪资工作,项目实训自然终止.,课程全程视频录制,偶尔耽搁也不担心,学习途中随时可以无理由退费根据学生情况,灵活安排授课时间,一个科目学不会可以免费学习另一个科目,全日制班,周末班,网上授课同时进行,在群里面随时会更新一些我们的课程视频以及开班动态198983438(加群请备注在哪里看到我们的群)
善知教育学习视频大汇总