什么是View

View和ViewGroup,用了组合模式

View的位置参数
top,left,right, bottom
x,y,transalationX,translationY(3.0新增参数)
x=left+transalationX
y=top+translationY
全部位置参数都相对于父容器

TouchSlop是系统所能识别出的被认为是滑动的最小距离。

VelocityTracker、GestureDetecetor、
Scroller

动画的兼容包 nineoldanimation在3.0之后动画移动的整个View本身,但在3.0之前只是移动View的内容,所以在3.0之前不能在view新的位置响应事件。

View的事件分发机制
(这个小节看的我很绕很绕,高能预警,非战斗人员迅速撤离~!!)

public boolean dispatchTouchEvent(MotionEvent ev)
用来进行事件的分发,如果事件能够传递给当前View,那么方法一定会被调用,返回结构受当前View的onTouchEvent和下级View的dispatchTouchEvent方法的影响,表示是否消耗当前事件。

public boolean onInterceptTouchEvent(MotionEvent ev)

在dispatchTouchEvent内部调用,用来判断是否拦截某个事件,如果当前View拦截了某个事件,那么在同一个事件序列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件。

public boolean onTouchEvent(MotionEvent ev)

在dispatchTouchEvent方法中调用,用来处理点击事件,返回结果表示是否消耗当前事件,如果不消耗,则在同一个事件序列中,当前View无法再次接收到事件。

关系伪代码如下

public boolean dispatchTouchEvent(MotionEvent ev){    boolean consume = false;    if (onInterceptTouchEvent(ev)) {        consume = onTouchEvent(ev);    } else {        consume = child.dispatchTouchEvent(ev);    }    return consume;}

事件传递机制的一些结论:
(1)同一个事件序列是指从手指接触屏幕的那一刻起,到手指离开屏幕的那一刻结束,在这个过程中所产生的一系列事件,这个事件序列以down事件开始,中间含有数量不定的move事件,最终以up事件结束。
(2)正常情况下,一个事件序列只能被一个View拦截且消耗,这一条的原因可以参考(3),因为一旦一个元素拦截了某事件,那么同一个事件序列内的所有事件都会直接交给它处理,因此同一个事件序列中的事件不能分别由两个View同时处理,但是通过特殊手段可以做到,比如View将本该自己处理的事件通过onTouchEvent强行传递给其他View处理。

(3)某个View一旦决定拦截,那么之一个事件序列只能由它处理(如果事件序列能够传递给它的话),并且它的onInterceptTouchEvent不会再被调用,这条也很好理解,就是说当一个View决定拦截一个事件后,那么系统会把同一个事件序列内的其他方法都直接交给它处理,因此就不用再调用这个View的onInterceptTouchEvent去询问它是否要拦截了。

(4)某个View一旦开始处理事件,如果它不消耗ACTION_DOWN事件(onTouchEvent返回了false),那么同一事件序列中的其他事件都不会再交给它来处理并且事件将重新提交由它的父元素去处理,即父元素的onTouchEvent会被调用。

(5)如果View不消耗除ACTION_DOWN以外的其他事件,那么这个点击事件会消失,此时父元素的onTouchEvent并不会被调用,并且当前View可以持续收到后续的事件,最终这些消失的点击事件会传递给Activity处理。

(6)ViewGroup默认不拦截任何事件,Android源码中ViewGroup的onInterceptTouchEvent方法默认返回false.

(7)View没有onInterceptTouchEvent方法,一旦有点击事件传递给它,那么它的onTouchEvent方法就会被调用。

(8)View的onTouchEvent默认都会消耗事件(返回true),除非它是不可以点击的(clickable 和 longClickable 同时为false).View的longClickable属性默认都为false,clickable属性要分情况,比如Button的clickable属性默认为true,而TextView的clickable属性默认为false。

(9)View的enable属性不影响onTouchEvent的默认返回值,哪怕一个View是diable状态,只要它的clickable或者longClickable有一个为true,那么它的onTouchEvent就返回true.

(10)onClick会发生的前提是当前View是可点击的,并且它收到了down和up的事件。

(11)事件传递过程是由外向内的,即事件总是先传递给父元素,然后再由父元素分发给子View,通过requestDisallowInterceptTouchEvent方法可以在子元素中干预父元素的事件分发过程,但是ACTION_DOWN事件除外。

事件传递:

Activity–>Window(PhoneWindow)–>mDecorView(FrameLayout)–>ContentView(布局顶层View,通常是ViewGroup)–>各个子Views

回调优先级:
OnTouchListener.onTouch() >View.onTouchEvent()>各种listeners

具体规则理解得多看书上的源码分析,这里就暂不分析了!

更多相关文章

  1. FAQ02963]如何拦截来电,即在电话ring之前就有机会检查来电号码?
  2. Android事件分发中的ViewGroup
  3. Android(安卓)之响应的系统设置的事件
  4. Android友盟统计和埋点
  5. Android(安卓)Spinner不触发onItemSelected事件
  6. Android(安卓)关于嵌套listView时onItemClick事件不响应的解决办
  7. 【Android】毫无耦合性,一个Item根布局搞定 item侧滑删除菜单,像IO
  8. RecyclerView实现Item点击事件方法二
  9. android事件处理总结--dispatchTouchEvent【转】

随机推荐

  1. Android 中文 API (90) ―― WindowManag
  2. Android通知Notification详解
  3. GPS 研究一 (Android2.3)
  4. LeakCanary源码分析
  5. Android IMF 学习笔记三
  6. Android(安卓)camera ISP相关 术语解释(
  7. Android中如何让手机屏幕不待机(PowerMana
  8. eclipse 在线安装android包:Download inte
  9. ActionBarSherlock的学习笔记(一) --------
  10. Android从零开始(26)(设置全屏+横屏、相