美文网首页
滑动冲突处理

滑动冲突处理

作者: 水清波 | 来源:发表于2019-08-14 11:31 被阅读0次

分2种:内部拦截和外部拦截

外部拦截

viewgroup用onInterceptTouchEvent处理,对需要的事件返回true拦截掉,子节点再也没有机会接触到事件,所有事件自己的ontouch处理。

内部拦截

子view通过requestDisallowInterceptTouchEvent可以让父view不再拦截事件
前提是down事件发生的时候viewgroup不能拦截,如果拦截了,view根本就没机会收到事件。
如果down事件到达了子view,viewgroup拦截move事件等,这种情况下,子view用requestDisallowInterceptTouchEvent优先在viewgroup的拦截前不允许拦截,就把move事件还是发送到子view里去。

以viewgroup解释
起点肯定是dispatchTouchEvent

            final int action = ev.getAction();
            final int actionMasked = action & MotionEvent.ACTION_MASK;
            if (actionMasked == MotionEvent.ACTION_DOWN) {
                cancelAndClearTouchTargets(ev);
                resetTouchState();
            }
//清除掉内部的TouchTarget链表,如果TouchTarget内有节点,发送当前事件给他们然后清理

//如果是ACTION_DOWN,做拦截判断,先用requestparentIntercept的标识判断
//后自己的onInterceptTouchEvent判断
//或者mFirstTouchTarget有值,说明自己在处理,这2种情况说明拦截了
            final boolean intercepted;
            if (actionMasked == MotionEvent.ACTION_DOWN
                    || mFirstTouchTarget != null) {
                final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
                if (!disallowIntercept) {
                    intercepted = onInterceptTouchEvent(ev);
                    ev.setAction(action); // restore action in case it was changed
                } else {
                    intercepted = false;
                }
            } else {
                // There are no touch targets and this action is not an initial down
                // so this view group continues to intercept touches.
                intercepted = true;
            }

down事件先清除了mFirstTouchTarget,所以down进入后后续的进入,都会判断是否被子类要求不拦截,子类要求不拦截后,才能走自己的onInterceptTouchEvent。
后续判断是否做了取消动作,
如果不取消不拦截一个分支:final ArrayList<View> preorderedList = buildTouchDispatchChildList();建立子child表用Z轴排序
dispatchTransformedTouchEvent去子child分发
如果分发成功,使用addTouchTarget加入一个TouchTarget节点

后续使用mFirstTouchTarget来判断,mFirstTouchTarget空说明没有加入到节点,说明没有child处理,吧自己当作普通view调用dispatchTransformedTouchEvent,由于内部没有child调用view.dispatchTouchEvent最终去触发ontouch了。
dispatchTransformedTouchEvent的结果被作为viewgroup.dispatchTouchEvent返回
这一系列就循环了。

TouchTarget是一个类似链表结构的有下级引用的内部静态类

private TouchTarget addTouchTarget(@NonNull View child, int pointerIdBits) {
        final TouchTarget target = TouchTarget.obtain(child, pointerIdBits);
        target.next = mFirstTouchTarget;
        mFirstTouchTarget = target;
        return target;
    }

addTouchTarget指出 mFirstTouchTarget是TouchTarget链表的表头,操作都在表头,就是一个栈

分发事件给子节点,没有子节点把自己当一个viwe处理,否则给子节点处理

private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
            View child, int desiredPointerIdBits) {
if (child == null) {
            handled = super.dispatchTouchEvent(transformedEvent);
        } else {
            final float offsetX = mScrollX - child.mLeft;
            final float offsetY = mScrollY - child.mTop;
            transformedEvent.offsetLocation(offsetX, offsetY);
            if (! child.hasIdentityMatrix()) {
                transformedEvent.transform(child.getInverseMatrix());
            }

            handled = child.dispatchTouchEvent(transformedEvent);
        }
}

相关文章

  • 滑动冲突处理

    分2种:内部拦截和外部拦截 外部拦截 viewgroup用onInterceptTouchEvent处理,对需要的...

  • 滑动冲突处理(一)

    滑动冲突场景:外层横向滑动,内层竖向滑动。这里通过外层拦截的方式来处理冲突。 注意:例子中得布局是ViewGrou...

  • 滑动冲突处理(二)

    滑动冲突场景:外层横向滑动,内层竖向滑动。这里通过内层拦截的方式来处理冲突。 注意:例子中得布局是ViewGrou...

  • Android 嵌套滑动冲突的处理

    移动开发中滑动冲突很常见,也有多种处理方式,今天谈下我现在的处理策略(基本和系统处理策略一致) 最常见的滑动冲突:...

  • 详解View的滑动冲突

    什么是滑动冲突? 滑动冲突较难使用语言进行直接描述,如果非要说,那就是:View体系中的滑动事件的实际处理和期望处...

  • Android滑动冲突处理

    导言 Android中的滑动冲突很常见,例如ScrollView/ListView,ViewPager/ViewP...

  • Android滑动冲突处理

    在我们平时项目开发的过程中,是不是会遇到滑动View之间的相互嵌套,比如外部的Scrollview或SwipeRe...

  • View滑动冲突处理

    http://www.jianshu.com/p/7d2c88ca24fc 滑动冲突处理一般在ACTION_MOV...

  • 滑动冲突的处理

    简单来说,处理滑动冲突,主要还是对view的事件分发的拦截的处理,原则就是 哪个view需要响应对应的滑动事件,就...

  • 处理View滑动冲突

    内部拦截法和外部拦截法 外部拦截法 ViewGroup可以拦截掉Move事件但是不能拦截掉Down事件,因为Vie...

网友评论

      本文标题:滑动冲突处理

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