Android触屏事件传递

一:前言


之前由于做Launcher部分,涉及到许多交互的部分,因为项目过去很长时间了,最近又在做GTS,CTS的测试与修改,好多都不熟悉甚至忘记了,结合别人的文章经验(我发现有些地方和别人有出入,但自己经测试验证),加上自己的测试,今天写下文章来总结一下。




二:关于ViewGroup与其中的view视图


  ViewGroup是一个容器类,一般,布局容器是继承字它的。容器里面可以存放视图,当然也可以嵌套容器,比如Relativelayout,LinearLayout等等。我这里所说的view视图是只继承view的类,没有继承容器类(ViewGroup)。因为后面降到的事件传递的小差异和这个有关系。继承自ViewGroup的类里面有interceptTouchEvent(),而没有继承ViewGroup的类没有这个方法,这个方法是负责拦截touch事件的。


三:事件传递 

  1:一般,针对ViewGroup ,事件传递有三个方法。


  •   dispatchTouchEvent(); 负责事件分发,如果返回值为true,表示事件不继续分发,也不进行消费(执行onTouchEvent(),如果onTouchEvent()返回true表示消费完,false表示没有消费完),然后一级一级向上执行容器类的dispatchTouchEvent(),并且每一级的返回值为true;如果dispatchTouchEvent()返回值为false,则交给父类分发给interceptTouchEvent();




  •   interceptTouchEvent();负责事件拦截,如果返回false,表示不拦截,touch事件交给下一级的视图处理,如果拦截,则交给这一级的onTouchEvent()来处理;




  •   onTouchEvent();负责消费事件,如果返回值为true,表示消费了事件,事件消失;如果返回值为false,则向上一级执行onTouchEvent(),如果上一级继续返回false,则继续向上,如果每一级都返回false,则进入死循环,导致ANR,android 5.1也会死循环,我测试不会导致ANR(可能公司手机还没有适配好),为了避免这种情况,可以在Activity的onTouchEvent()返回true;


........... extends Activity{

    public boolean dispatchTouchEvent(MotionEvent ev) { 

        return true;
    }
}

  2:针对不是容器类的View


  •    dispatchTouchEvent(); 负责事件分发,如果返回值为true,表示事件不继续分发,也不进行消费(执行onTouchEvent(),如果onTouchEvent()返回true表示消费完,false表示没有消费完),这里注意了,一般这个View都存在于一个容器中,但是不执行父容器的dispatchTouchEvent(),而是执行父父容器的dispatchTouchEvent(),然后向上递归传递,为什么?个人觉得是:因为没有继承ViewGroup的(不是容器类),它没有子View,他和父容器的dispatchTouchEvent()处理时是调用的同一个,所以虽然有事件分发函数;如果dispatchTouchEvent()返回值为false,则交给父类分发给onTouchEvent()消费;个人感觉最好不要在dispatchTouchEvent()里面强行返回false,并且在里面做UI处理。






  •    onTouchEvent();负责消费事件,如果返回值为true,表示消费了事件,事件消失;如果返回值为false,则向上一级执行onTouchEvent(),如果上一级继续返回false,则继续向上,如果每一级都返回false,则进入死循环,导致ANR,android 5.1也会死循环,我测试不会导致ANR(可能公司手机还没有适配好),为了避免这种情况,可以在Activity的onTouchEvent()返回true;


dispatchTouchEvent()和onTouchEvent();


   一个事件开始于Activity的dispatchTouchEvent()方法,并向DecorVIew(setContentView()里面的view)下面传递的.