Android 之在View以及ViewGroup中Touch事件传递

    xiaoxiao2023-03-24  4

    关于onTouch事件的系统学习,是参考:基于源码来了解Android的事件分发机制

    个人总结:事件的分发还是基于View的视图树,进行递归遍历

    ①首先在ViewGroup中,先判断父控件(父View)是否进行拦截事件 onIntercept()。

    ②父View没有拦截,在dispatchTouchEvent中遍历子View的dispatchTouchEvent事件。

    ③在子View的dispatchTouchEvent事件中,判断当前子View是否注册了onTouchListener。

    如果注册了,就执行onTouchEvent事件。

    ④如果当前子View没有注册onTouch事件,就回到父View的dispatchTouchEvent事件中,

    遍历子View,知道遍历完成,没有子View去注册onTouchListener事件,就会调用

    父View的super.dispatchTouchEvent()方法,来触发自己的监听器。

    ⑤子View注册了onTouchListener监听器,在ACTION_DOWN中,监听长按方法,通过一个Runnable对象,

    来检测是当前子View是否注册了onLongClickListener监听事件。并设置一个boolean属性

    mHasPerformLongPress = true。

    ⑥在当前注册了onTouchListener的ACTION_UP方法中,根据mHasPerformLongPress = fasle;时

    检测当前子View是否注册了onClickListener监听。

    执行顺序就是:

    ViewGroup : onInterceptTouchEvent > ViewGroup : dispatchTouchEvent > View : dispatchTouchEvent

    > View : onTouchEvent > View : onLongClick > View : onClick

    如果遍历子View 没有注册onTouchListener,就调用:

    ViewGroup : onInterceptTouchEvent > ViewGroup : dispatchTouchEvent > View : dispatchTouchEvent

    ViewGroup :onTouchEvent > ViewGroup : onLongClick > ViewGroup : onClick

    返回true,表示当前View消费了该事件,事件不再往下传递。

    如果父View拦截消费了该事件,就会向子View传递一个ev.setAction(ACTION_CANCEL);

    表示父View拦截消费了该事件,也是往子View传递的最后一个事件ACTION_CANCEL。

    Tips:关于MotionEvent的几个API:

    ①ev.getX();//当前的X、Y坐标是基于父布局View的相对坐标值。即在父View左上角原点的(X,Y)坐标点。相对坐标

       ev.getY();

       ev.getRawX();//当前的X、Y坐标就是基于屏幕左上角原点的(X,Y)坐标点。绝对坐标。

       ev.getRawY();

    ②关于View上的ACTION_DOWN,ACTION_MOVE,ACTION_UP的一系列叫做事件流。

       如果当前View接收了父View视图的ACTION_DOWN,即在ACTION_DOWN中返回true,

       那么与ACTION_DOWN 相关的事件流都要分发给当前的子视图View。

       但是,父视图希望拦截其中的一些事件,不继续传递给子视图View,就需要给子视图

       传递一个ACTION_CANCEL事件。

    关于多点触控的,pointer 的 

    MotionEvent.ACTION_POINTER_DOWN:代表用户的第二根手机触碰屏幕

    MotionEvent.ACTION_POINTER_UP:代表用户多点触控的第一个手指离开屏幕

    每一个pointer都会有自己的id,index。

    整个事件流中,pointer的id不会发生变化,但是index会发生变化。

    int index = event.getActionIndex();

    int mActivePointerId = event.getPointerId(index);

    自己先对多点触控,留个坑,不是今天学习主线。国庆十月五号补全。立个flag。

    转载请注明原文地址: https://ju.6miu.com/read-1202762.html
    最新回复(0)