Android中View的事件冲突

原创 2018年04月17日 16:50:14

仅限于自己学习的笔记,有不正确的地方望指正。

常见的滑动冲突的场景

  1. 外部滑动方向和内部滑动方向不一致。
  2. 外部滑动方向和内部滑动方向一致。
  3. 以上两种嵌套。

    场景1:主要是ViewPager和Fragment配合使用组成的滑动效果。主流应用几乎都是使用这个效果。在这种效果中,可以通过左右滑动来切换界面,而每个页面的内部往往有是一个ListView。本身这种情况下是有冲突的。但是ViewPager内部处理了这种冲突。因此我们使用时候无需关系这类问题。

    场景2:内外两层同时上下滑动或者内外两层同时左右。例如ScrollView嵌套RecycleView导致滑动卡顿的现象。

    场景3:外部是SlideMenu效果,然后内部有一个ViewPager,ViewPager每个界面是ListView。


滑动冲突的处理原则

  • 场景1:当用户左右滑动时候,需要让外部的View拦截点击事件,当用户上下滑动时,需要让内部View拦截点击事件。这样我们可以根据特征来区分到底是左右滑动还是上下滑动。(可以根据滑动的两点坐标区分到时是左右滑动还是上下滑动)
  • 场景2:可以根据业务规定,当处于某种状态时需要外部View滑动,当处于某种状态时需要内部的View滑动。
  • 场景3:结合以上两种情况综合分析,处理滑动冲突,按照一定的规则处理。

    Viewtouch事件分发过程中重要的三个函数

  • dispatchTouchEvent 负责touch事件的分发
  • onInterceptTouchEvent 负责拦截touch事件
  • onTouchEvent 最终处理touch事件

滑动冲突的解决方式

  1. 外部拦截法
    外部拦截法就是点击事件都先经过父容器的拦截处理,如果父容器需要拦截则拦截,反之不需要则不拦截。此方法符合View事件分发机制。
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;
            break;
        }
        case MotionEvent.ACTION_MOVE: {
            if(父容器拦截的规则){
                intercepted=true;
            }else{
                intercepted=false;
            }
            break;
        }
        case MotionEvent.ACTION_UP: {
            intercepted = false;
            break;
        }
        default:
            break;
        }
        mLastXIntercept=x;
        mLastYIntercept=y;
        return intercepted;
    }

此方法只是父元素在ACTION_MOVE事件中根据条件判断是否拦截。其他事件则不需要处理。如果拦截了则下层子元素接收不到事件。
2. 内部拦截法
内部拦截法只是父元素不拦截事件,全部交给子元素处理事件。如果子元素需要拦截则拦截,否则交给父容器拦截。需要配合requestDisallowInterceptTouchEvent方法才能正常执行。

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-mLastXIntercept;
            int deltaY=y=mLastYIntercept;
            if(父容器需要拦截的事件){
                parent.requestDisallowInterceptTouchEvent(false); //父布局需要要拦截此事件
            }
            break;
        }
        case MotionEvent.ACTION_UP: {
            intercepted = false;
            break;
        }
        default:
            break;
        }
        mLastXIntercept=x;
        mLastYIntercept=y;
        return super.dispathTouchEvent(event);
    }

当需要父元素拦截时则调用父容器的requestDisallowInterceptTouchEvent(false)方法。父元素要默认拦截除了ACTION_DOWN以外的其他事件否则所有的子元素无法收到事件。

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

参考:Android开发艺术探讨

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sky1373516909/article/details/79976115

什么是XForms?

什么是XForms?当前的Web表单的设计无法从表单的表述中分离表单的目的或用途,然而XForms, , 由分别描述表单行为和样式的独立单元组成,这就允许柔性表述选择, 包含经典的XHTML表单,附加...
  • FlySpace
  • FlySpace
  • 2003-05-17 17:29:00
  • 1513

Android 中触摸事件与点击事件分析

  • 2017年04月28日 12:25
  • 2KB
  • 下载

Android技术之View的事件分发机制和滑动冲突解决方案

本文转载:http://mp.weixin.qq.com/s/fhr3u2iA-R8J4WdRtMqWGAReact-Native学习指南,汇集React-Native各类学习资源,给大家提供便利,并...
  • wanghonghuai
  • wanghonghuai
  • 2017-02-17 10:57:51
  • 1135

Android view 滑动事件冲突解决方法(理论篇)

1.外部拦截法: 通过父容器拦截处理,如果父容器需要就拦截,如果父容器不需要就不拦截交给子view;主要是修改父容器的 onInterceptTouchEvent 方法,伪代码如下:@Ov...
  • a1018875550
  • a1018875550
  • 2016-07-06 16:09:59
  • 825

一文解决Android View滑动冲突

上一篇文章我们讲述了Android View事件分发机制。如果你对View的事件分发还不熟悉,建议先去看一下 一文读懂Android View事件分发机制 它是我们今天滑动冲突解决的理论基础! 如果...
  • u010302764
  • u010302764
  • 2017-05-27 09:57:06
  • 3252

通俗理解Android中View的事件分发机制及滑动冲突处理

说起Android滑动冲突,是个很常见的场景,比如SliddingMenu与ListView的嵌套,要解决滑动冲突,不得不提及到View的事件分发机制。 一、Touch事件传递规则分析 首先,我们要...
  • yyh352091626
  • yyh352091626
  • 2016-02-25 13:47:40
  • 12575

由View点击和长按同时存在导致冲突看View的事件分发

如果一个View同时设置了点击监听setOnclickListener和长按setOnLongClickListener时,这时如果你想长按的时候弹出一个对话框,点击的时候跳转到另一个页面的时候,如下...
  • qq_32113133
  • qq_32113133
  • 2017-01-19 21:21:03
  • 490

Android 笔记 ViewPager的滑动与子view内部滑动事件的冲突问题

ViewPager 与子view的滑动冲突在上一次笔记中建设了一个可以滑动的photoView,显示图片,可以放大,滑动大部分时候这个自定义View会和ViewPager一起使用。也就是我们通常看到...
  • super_zq
  • super_zq
  • 2016-10-13 14:14:43
  • 1724

Android中滑动事件冲突的处理方法

滑动是Android中不可缺少的一部分,多个滑动必然会产生冲突,比如我们最常见的是ScrollView中嵌套了ListView,一般做法是计算出ListView的总高度,这样就不用去滑动ListVie...
  • lylodyf
  • lylodyf
  • 2016-09-06 09:04:00
  • 2530

View的事件体系(下)(事件分发,滑动冲突)

View的事件分发机制是一个核心知识点也是解决滑动冲突的理论基础。本篇博文会深入分析View的事件分发机制。 一 View的事件分发机制 (1).点击事件的传递规则 在介绍点击事件传递之前,首先...
  • Tyssen
  • Tyssen
  • 2016-01-19 18:45:58
  • 1029
收藏助手
不良信息举报
您举报文章:Android中View的事件冲突
举报原因:
原因补充:

(最多只允许输入30个字)