zoukankan      html  css  js  c++  java
  • android View事件分发机制结论

      原始博客有对源码的分析:http://blog.csdn.net/lmj623565791/article/details/39102591

    结论:1.view事件的分发流程:

      dispatchTouchEvent -> setOnTouchListener(onTouch) -> onTouchEvent。

    View拦截到事件之后首先在dispatchTouchEvent中判断是否设置了监听,如果没有就调用onTouchEvent,onTouchEvent默认返回的是true消费事件,如果返回false最后将有ParentView处理事件。

    如果在setOnTouchListenner中返回时true说明消费了这个事件,那么后续的onTouchEvent将不会执行。

         2.onTouchEvent中的move down up

    a、首先设置标志为PREPRESSED,设置mHasPerformedLongPress=false ;然后发出一个115ms后的mPendingCheckForTap;

    b、如果115ms内没有触发UP,则将标志置为PRESSED,清除PREPRESSED标志,同时发出一个延时为500-115ms的,检测长按任务消息;

    c、如果500ms内(从DOWN触发开始算),则会触发LongClickListener:

    此时如果LongClickListener不为null,则会执行回调,同时如果LongClickListener.onClick返回true,才把mHasPerformedLongPress设置为true;否则mHasPerformedLongPress依然为false;

    MOVE时:

    主要就是检测用户是否划出控件,如果划出了:

    115ms内,直接移除mPendingCheckForTap;

    115ms后,则将标志中的PRESSED去除,同时移除长按的检查:removeLongPressCallback();

    UP时:

    a、如果115ms内,触发UP,此时标志为PREPRESSED,则执行UnsetPressedState,setPressed(false);会把setPress转发下去,可以在View中复写dispatchSetPressed方法接收;

    b、如果是115ms-500ms间,即长按还未发生,则首先移除长按检测,执行onClick回调;

    c、如果是500ms以后,那么有两种情况:

    i.设置了onLongClickListener,且onLongClickListener.onClick返回true,则点击事件OnClick事件无法触发;

    ii.没有设置onLongClickListener或者onLongClickListener.onClick返回false,则点击事件OnClick事件依然可以触发;

    d、最后执行mUnsetPressedState.run(),将setPressed传递下去,然后将PRESSED标识去除;

    注意:1.SetonLongClickListener与SetonClickListener是否只能执行一个?不是的在public boolean onLongClick(View v)返回如果是false将会继续执行onCliclk返回true就不会执行。

    另外对于onTouchEvent中的move与up如果在setOnTouchEvent中拦截了事件,那么onTouchEvent不会执行后续所有的move click longclick 都不会执行了。

    这个只不过是自己的流水账,偶尔有一些心得,错误的地方概不负责
  • 相关阅读:
    设计模式之三:Abstract Factory(转)
    设计模式之二:adapter模式(转)
    设计模式之一:设计原则(转)
    双链表操作
    单链表操作
    C#-Activex插件操作指南
    积分源码上线
    換友情鏈接
    企业短信群发
    掉了,全掉了。
  • 原文地址:https://www.cnblogs.com/ashitaka/p/6040340.html
Copyright © 2011-2022 走看看