Android开发艺术探索笔记 第三章
View事件体系
- view的位置有四个定点来决定,这些坐标都是相对于view的父容器来说的
- 左上角是left和top右下角是right和bottom
- getx、y是相对于当前view左上角,getRawX、Y是相对于屏幕左上角
- TouchSlop是系统所能识别出对被认为最小的滑动距离,是一个常量和设备有关
- VelocityTracker速度追踪,用来计算单位ms内滑过的像素,速度有方向可以为负数
- GestureDetector手势检测,和onTouchevent不共存,滑动建议使用onTouchEvent双击建议使用Gesture
- Scroller和View的computeScroll配合实现弹性滑动
- 实现滑动的三种方式1:View自身方法scrollTo、scrollBy操作简单不影响内部元素的点击事件,;2:利用动画,适合做没有交互并且动画复杂的滑动;3:改变LayoutParams重新布局,使用操作复杂适合具有一定交互性的View
- scrollTo不能改变view的位置改变的是内容的位置
- nineoldandroids兼容3.0一下版本的属性动画,本质上仍然是View动画
- 弹性滑动的思想是把一次大的滑动分解成若干小的滑动,并且在一段时间内完成
- invalidate会导致View重绘,View的draw方法又会调用computescroll方法
View的事件分发机制
- 分发的对象为MotionEvent
- dispatchTouchEvent:如果事件能传递到当前view,那此方法一定会调用,返回结果收当前view的onTouchEvent和下级view的dispatchTouchevent方法影响
- onInterceptTouchEvent:如果当前view拦截了某个事件,那么在同一时间序列中,此方法不会再次调用
- onTouchEvent: 表示是否消耗当前事件,如果不消耗则在同一事件序列中,当前view无法再次接收到事件
- onTouchListener优先级高于onTouchEvent高于onClickListener
- 点击事件以down开始以up结束
- 一个事件序列只能被一个View拦截且消耗
- view开始处理时间,如果他不消耗down,那么其他事件就不再交给他处理,重新交给他的父控件处理
- viewgroup默认不消耗任何事件
- view没有InterceptTouchEvent,一旦有事件传递给他,他的onTouchEvent就会调用
-view的onTouchEvent默认都会消耗事件,除非他是不可点击的clickable和longclickable都是false - view的longClickable默认都是false,clickable看情况
- decorview一般就是当前页面的底层容器
- window的惟一实现就是phoneWindow,phoneWindow直接将事件传递给了decorview
- 源码中是通过设置标记为来记录消费事件的view
view的滑动冲突
- 常见的滑动冲突一共有三种;1内外滑动方向不一致,2内外滑动方向一致,3上面两种方式的嵌套
- viewpager内部处理了滑动冲突
- 不管多复杂的滑动冲突,他们之间的区别仅仅是滑动规则不同
- 外部拦截法父控件不能拦截down,不然子控件没有机会处理事件,父控件不拦截up,因为up本身没有太多意义,需要重写父控件的onInterceptTouchEvent
- 内部拦截法,父控件不拦截任何事件。需要重写子空间的dispatchTouchEvent配合requestDisallowInterceptTouchEvent