美文网首页
事件分发

事件分发

作者: WangRain1 | 来源:发表于2020-05-29 10:54 被阅读0次

/**

*

* ViewRootImpl -注册-> activity -》 decorview -》 ViewGroup -》 View

* ViewGroup.dispatchTouchEvent

*          返回 true 自身的 onTouchEvent

*              false 不拦截,会传递给父view的onTouchEvent

*              super.dispatchTouchEvent

*                    onIntercepterTouchEvent true 自己拦截,调用自己的Ontouchevent

*                                            super.onIntercepterTouchEvent  默认返回true

*                                            false 不拦截,调用子view的 dispatchTouchEvent

*                                                    子view 响应 touchListener /onTOuch /onClick

*

*    如果view 的 ontouchEvent 返回true 就消费,false 传递给上层view的ontouchEvent

*/

《事件流》==> 每一组事件从 action down 开始传递、到action up 结束。

在这个流中在某个view的事件处理方法中如果全部返回false就是都不处理这个事件,都不处理的话,事件会重复贯穿整个事件传递过程。

例如:down 事件会传递整个view树的down事件,move事件会传递整个view 树的move事件,都不处理到activity ontouch 事件结束传递。

如果:在某一个view的事件处理中onIntercepter返回了true,那就会走这个view的ontouch进行消费,

这个事件流就不会再走onIntercepter方法判断是否拦截了。比如move的时候onIntercepter返回true,那么之后的事件就之走该view的ontouch。false的话会重复走onIntercepter判断当前是否拦截。==>《指的是当前这个流从 DOWN ==> UP》

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

switch (ev.getAction()) {

case MotionEvent.ACTION_DOWN:

break;

        case MotionEvent.ACTION_MOVE:

break;

        case MotionEvent.ACTION_UP:

break;

    }

// 继续分发到 onInterceptTouchEvent

    return super.dispatchTouchEvent(ev);

}

@Override

public boolean onInterceptTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

break;

        case MotionEvent.ACTION_MOVE:

break;

        case MotionEvent.ACTION_UP:

break;

    }

/**

*  1.传递给子view中,让子view自行判断是否需要拦截调用view.dispatchTouchEvent(),

*  如果子view拦截就不会走,父view的 onTouchEvent。

*  就说明事件交给了,子view处理。

*/

    return super.onInterceptTouchEvent(event);

}

float startX;

float startY;

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

startX = event.getX();

            startY = event.getY();

break;

        case MotionEvent.ACTION_MOVE:

if ((event.getX() -startX) < -touchSlop) {

return true;

            }

return super.onTouchEvent(event);

        case MotionEvent.ACTION_UP:

break;

    }

/**

* 1.如果子view不处理,子view会把事件传递给,父的onTouchEvent。

* 2.父view如果在特殊情况下需要拦截,

* 例如:在向左滑动的时候需要拦截,那就在父view中先返回true,先自己拦截下来。

* 然后调用 ACTION_MOVE,在 ACTION_MOVE 中根据自己的条件判断是拦截还是不拦截,

* 不拦截继续传递给 activity 的onTouchEvent处理。

*/

    return true;

}

让事件循环传递:

@Override

public boolean onInterceptTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

startX = event.getX();

            startY = event.getY();

break;

        case MotionEvent.ACTION_MOVE:

// control travel show.

            if (null !=drag && !drag.isShowTravel() && (event.getX() -startX) < -touchSlop

                    && isHorizontalScroll(event)) {

return true;

            }else if (null !=drag &&drag.isShowTravel() && (event.getX() -startX) >touchSlop

                    && isHorizontalScroll(event)){

// control travel dismiss.

                return true;

            }

return super.onInterceptTouchEvent(event);

        case MotionEvent.ACTION_UP:

break;

    }

return false;

}

###############################
一个正在被触摸的View 隐藏/消失对事件的影响:事件会被作用到View下面的view 上。
一个正在被点击的VIew被突然出现的view 覆盖事件的传递:事件还是作用在之前view 上,新出现的View 是拿不到事件的。

相关文章

网友评论

      本文标题:事件分发

      本文链接:https://www.haomeiwen.com/subject/ytpzahtx.html