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;
        }
    }

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

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

  • 相关阅读:
    一直在维护一些项目,其实 这些项目也没有太大的需求,
    iis 7 url 重写
    xmlapp 如何配置
    [转载]什么是native compiler?什么是cross compiler?
    CDC工具
    EDA工具介绍(数字设计)
    让FPGA初学者头疼的各种仿真【转载】
    [SOF] Pointers, smart pointers or shared pointers?
    GNU的工具gmake and make
    mealy machine和moore machine
  • 原文地址:https://www.cnblogs.com/lesliefang/p/5277554.html
Copyright © 2011-2022 走看看