zoukankan      html  css  js  c++  java
  • Android 滑动冲突处理

    要想解决滑动冲突就必须好好理解 Android 的事件分发机制。不了解 Android 事件分发机制的请先参考资料学习一下。

    一般有 2 种方法

    1 外部拦截法

    这个非常简单,因为事件是从父 view 向子 view 进行分发的,所以我们可以重写父控件的 onInterceptTouchEvent, 如果父容器需要某个事件就拦截,如果不需要就不拦截交给子view处理。

    伪代码如下

    public boolean onInterceptTouchEvent(MotionEvent event) {
        boolean intercept = false;
        int x = (int) event.getX();
        int y = (int) event.getY();
    
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                intercept = false;
                break;
            case MotionEvent.ACTION_MOVE:
                if (父容器需要这个事件) {
                    intercept = true;
                } else {
                    intercept = false;
                }
                break;
            case MotionEvent.ACTION_UP:
                intercept = false;
                break;
        }
    
        mLastX = x;
        mLastY = y;
    
        return intercept;
    }

    这里有一点需要注意,父容器不能拦截 ACTION_DOWN 事件,因为父容器一旦拦截了 ACTION_DOWN 事件那么后面所有的事件就都由它来处理了,子 view 就接收不到任何事件了。

    2 内部拦截法

    父容器不拦截任何事件,所有的事件都传递给子元素,如果子元素需要此事件就直接消耗掉,否则交给父容器就行处理,需要配合 requestDisallowInterceptTouchEvent 来干预父容器对事件的拦截。

    伪代码如下

    一要重写子view的 dispatchTouchEvent

    public boolean dispatchTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
    
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                parent.requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX = x - mLastX;
                int deltaY = y - mLastY;
                if (父容器需要这个事件) {
                    parent.requestDisallowInterceptTouchEvent(false);
                }
                break;
        }
    
        mLastX = x;
        mLastY = y;
    
        return super.dispatchTouchEvent(event); // 干预之后再扔给父容器
    }

    二要重写父容器的 onInterceptTouchEvent 让父容器默认拦截除 ACTION_DOWN 以外的所有事件

    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            return false;
        } else {
            return true;
        }
    }

    内部拦截法不太好理解,比较饶。

    外部拦截法与事件分发机制流程一致,简单好理解,所以一般情况下都会优先选择外部拦截法。

  • 相关阅读:
    WinAPI: SetRect 及初始化矩形的几种办法
    [书目20080225]软件工程与项目管理解析
    [转]npkcrypt 服务启动失败
    CPU是为用户服务的
    Web.config基础
    VBScript学习
    [书目20080130]如何成功管理一个软件项目
    [转]DB2常用命令大全
    [转]C++语法概括及其示例(示例代码下载)
    用友华表Cell产生柱状图表
  • 原文地址:https://www.cnblogs.com/lesliefang/p/5277554.html
Copyright © 2011-2022 走看看