View的事件体系

0. 事件的定义

  1. 首先这章集中在View 的事件体系,所以键盘事件(keyevent)就先不说了
  2. view的事件定义为motionevent,其中各个view,viewgroup分发的均是motionevent,只是各自的流程不一样,同时,gesturedetector 能监测的也是motionevent

点击事件的分发,其实就是将产生的一个motionevent(一下简称为event或事件)传递给一个具体的view被处理掉,传递过程即为事件的分发过程

1. 分发过程

  • 首先说明一个东西 viewgroup 继承自view,但是事件的分发一定是从一个viewgroup开始的,如果不是,那就不用分发了,直接由view自己处理了
  • 一段伪代码镇楼

      public boolean dispatchTouchEvent(MotionEvent event) {
          boolean consumed = false;
          if(onInterceptTouchEvent(event)){
              consumed = ontouchevent(event);
          }else{
              for(int i=0;i< childcount,i++) {
                  consumed = child.dispatchTouchEvent(MotionEvent event);
                  if(consumed){
                      break;
                  }
              }
          }
          return consumed;
      }
    

    onInterceptTouchEvent(event) 这个方法是viewgroup特有的,用来判断事件是否是自己处理,需要自己处理,调用ontouchevent.这段代码的逻辑很清晰,就是该我处理的我处理,不该我处理的给儿子们处理.

    给出一些结论更好的理解整个过程

    • 同一个事件序列是指从手指接触屏幕那一刻起,到手指离开屏幕那一刻结束,在这个过程中所产生的一些列事件,这个事件序列以down事件开始,up事件结束,中间含有数量不定的move事件
    • 正常情况下,一个事件只能被一个View拦截消耗,这一条原因可以参考(3),因为一旦某个元素拦截了此次事件,那么同一个事件的序列的所有事件都会直接交给它处理,因此同一个事件序列中的事件不能同时交给两个view处理
    • 某个view一旦决定拦截事件,那么这个事件的所有序列都会交给它来处理(如果他能收到事件)
    • 某个view一旦开始处理事件,如果它不能消耗掉down事件的话,那么这个事件序列的move和up事件将不会再交给他处理
    • 如果view不消耗除down事件的其他事件,那么这个事件会消失,同时不会回调给父布局(因为这个事件序列的down,开始事件已经交给这个view处理了),最后的事件会交给activity处理。(这条不理解了)
    • viewgroup默认不拦截任何事件
    • view没有onInterceptTouchEvent(event),一旦有点击事件,交给ontouchevent处理
    • view的ontouchevent默认返回true,除非是不可点击的。
st=>start: Activity
e=>end: END
op1=>operation: Window
op2=>operation: PhoneWindow
op3=>operation: DecoView
op4=>operation: contentviewgroup
op5=>operation: Viewgroups
op6=>operation: View
op7=>operation: ontouchevent
sub1=>subroutine: My Subroutine
cond1=>condition: onInterceptTouchEvent(event)
cond2=>condition: onTouchEvent(event)
st->op1->op2->op3->op4->op5->cond1
cond1(yes)->op7->e
cond1(no,right)->op6->cond2
cond2(yes)->e
cond2(no)->op5

results matching ""

    No results matching ""