滑动事件冲突

作者: 小菜_charry | 来源:发表于2016-07-25 13:11 被阅读327次

滑动事件冲突

一般分三种:

  • 滑动方向一致导致的冲突
  • 滑动方向不一致导致的冲突
  • 滑动方向的各种叠加导致的冲突

解决方案分两种:

  • 外部拦截法

    由外层父容器来处理,在父容器的onInterceptTouchEvent中决定是否需要拦截

  • 内部拦截法

    由内部子容器处理,在子容器中的dispatchTouchEvent中通过requestDiallowInterceptTouchEvent来申请父容器不拦截。

外部拦截

在父容器的onInterceptTouchEvent中决定是否需要拦截。
下面的父容器判断:水平方向大于竖直方向,则拦截

if (Math.abs(deltaX) > Math.abs(deltaY)) {
    intercepted = true;
} else {
    intercepted = false;
}

只需要根据需求改变判断的条件即可,完整代码:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    boolean intercepted = false;
    int x = (int) event.getX();
    int y = (int) event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN: {
        intercepted = false;
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
            intercepted = true;
        }
        break;
    }
    case MotionEvent.ACTION_MOVE: {
        int deltaX = x - mLastXIntercept;
        int deltaY = y - mLastYIntercept;
        if (Math.abs(deltaX) > Math.abs(deltaY)) {
            intercepted = true;
        } else {
            intercepted = false;
        }
        break;
    }
    case MotionEvent.ACTION_UP: {
        intercepted = false;
        break;
    }
    default:
        break;
    }

    Log.d(TAG, "intercepted=" + intercepted);
    mLastX = x;
    mLastY = y;
    mLastXIntercept = x;
    mLastYIntercept = y;

    return intercepted;
}

内部拦截

内部拦截是子容器请求父容器不拦截的做法。需要配合requestDisallowInterceptTouchEvent使用。父容器也要稍微做些变动,相对来说复杂了点。

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    int x = (int) event.getX();
    int y = (int) event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN: {
        mHorizontalScrollViewEx2.requestDisallowInterceptTouchEvent(true);
        break;
    }
    case MotionEvent.ACTION_MOVE: {
        int deltaX = x - mLastX;
        int deltaY = y - mLastY;
        Log.d(TAG, "dx:" + deltaX + " dy:" + deltaY);
        if (Math.abs(deltaX) > Math.abs(deltaY)) {
            mHorizontalScrollViewEx2.requestDisallowInterceptTouchEvent(false);
        }
        break;
    }
    case MotionEvent.ACTION_UP: {
        break;
    }
    default:
        break;
    }

    mLastX = x;
    mLastY = y;
    return super.dispatchTouchEvent(event);
}

上面例子中,若水平方向上大于垂直方向,则交由父容器来处理,其他情况都有字容器来处理。所以父容器需要变动:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    int x = (int) event.getX();
    int y = (int) event.getY();
    int action = event.getAction();
    if (action == MotionEvent.ACTION_DOWN) {
        return false;
    } else {
        return true;
    }
}

变动:若是ACTION_DOWN则不拦截,也不能拦截。其他时候都要拦截。这样只有在子容器请求父容器不拦截的时候才交由子容器来处理点击事件。

相关文章

  • Android滑动事件冲突解决方法

    1.Android滑动事件冲突解决办法 滑动事件的冲突包括两种情形: 不同方向的滑动冲突:比如ScrollView...

  • Android View | View 的滑动冲突

    滑动冲突在实际项目中十分常见,解决滑动冲突的核心是结合事件的分发机制,了解事件的分发可参考这里。 常见的滑动冲突场...

  • iOS开发中遇到的问题 小计

    事件冲突 解决scrollView的滑动事件与子视图按钮事件冲突self.scrollView.panGestur...

  • ScrollView 嵌套 RecyclerVeiw, 轻松解决

    滑动冲突 在开发android中, 滑动冲突是一常见的事件冲突。列如:在scrollView中嵌套listView...

  • 滑动事件冲突

    滑动事件冲突 一般分三种: 滑动方向一致导致的冲突 滑动方向不一致导致的冲突 滑动方向的各种叠加导致的冲突 解决方...

  • Android系统知识全览---View知识体系(2)---Vi

    View的事件体系 View的概念 View的事件 View的滑动事件 View事件分发机制 View的滑动冲突解...

  • 事件冲突

    事件冲突在日常开中会经常碰到,比如滑动冲突 、点击事件冲突等等。常见的如ScrollView中嵌套ListView...

  • Android ScrollView 嵌套RecyclerVie

    ScrollView 和RecyclerView都是滑动组件,因此存在滑动事件冲突问题,解决思路就是在事件分发函数...

  • Android应用开发三部曲 --- Touch事件分发

    1、前言 Android应用开发中,经常会遇到touch事件分发的问题,甚至还会遇到滑动冲突问题,如果解决滑动冲突...

  • 详解View的滑动冲突

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

网友评论

    本文标题:滑动事件冲突

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