当我们手指按下时,Android采用层层传递-冒泡的方式处理点击事件。例如,现在公司来了个小项目,老板一看分配给经理做,经理一看分配给小组长,小组长一看好简单,分配给组员。如果在这个传递过程中(也就是还为分配到最底部时),某一层觉得我来负责这个比较好的话就会拦截掉这个消息,然后把它处理了,下面的就收不到有消息的这个通知。如果一直到了底层的话,组员如果能完成,就完成它。如果不能完成,那么就报告给组长,说组长我做不来,边学边做要影响进度。组长一看我也做不来,就给经理,经理一看我也不会,就给老板。这样也就一层层的传递了。 
      以上的意思也即:消息从上到下依次传递,如果在传递的过程中被拦截了就停止下传。如果没有被拦截,就一直传递到底部,如果底部不能够消耗该消息,那么就又一层层的返回来,返给上层,直到被消耗或者是到达最顶层。在此过程中,存在三个重要的方法:

    dispathTouchEvent(MotionEvent ev)  
负责事件的分发,它的返回值就是表示是否消耗当前事件;
onInterceptTouchEvent(MotionEvent ev)
用于判断是否拦截该消息,如果当前View拦截了某个时间,那么在同一个事件序列中,此方法不会被再次调用。返回结果表示是否拦截当前事件 。
onTouchEvent(MotionEvent ev)
处理事件。返回结果表示是否消耗当前事件,如果不消耗,则在同一时间序列中,当前View无法再次接收到事件。

对于一个根ViewGroup来说,点击事件产生后,首先会传递给它,并调用它的dispath方法。如果这个ViewGroup的onIntercept方法返回true就表示它要拦截当前事件,false就表示不拦截,这个时候事件就会继续传递给子元素,接着调用子元素的dispath方法,一直重复以上过程到事件被处理。

下面介绍一下常见的问题及解决方法:

一、滑动冲突

View的滑动冲突产生愿意大概可以分为三种:

  • 外部滑动和内部滑动方向不一致
  • 外部滑动方向和内部滑动方向一致
  • 嵌套上面两种情况

比如说一个常见的,外部一个ListView,里面一个ScrollView,滑动时出现冲突?

此时一般是采用外部拦截法(即结合onInterceptTouchEvent、onTouchEvent)来进行解决。具体方法如下:

   (1)外部拦截法

      外部拦截法就是指所有的点击时间都经过父容器的拦截处理,如果父容器需要此事件就拦截,如果不需要此事件就不拦截。通过重写父容器的onInterceptTouchEvent方法:

 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;
return intercepted;

注:ACTION_DOWN事件父类容器就必须返回false,因为如果父类容器拦截了的话,后面的Move等所有事件都会直接由父类容器处理,就无法传给子元素了。UP事件也要返回false,因为它本身来说没有太多的意义,但是对于子元素就不同了,如果拦截了,那么子元素的onClick事件就无法触发。

内部拦截法 
这种方法指的是父容器不拦截任何时间,所有的事件都传递给子元素,如果子元素需要此事件就直接消耗掉,否则就交给父容器进行处理。它需要配合requestDisallowInterceptTouchEvent方法才能正常工作。我们需要重写子元素的dispatch方法。

    case MotionEvent.ACTION_DOWN:
parent.requestDisallowInterceptTouchEvent(true);
break;
MotionEvent.ACTION_MOVE:
if(父容器需要此类点击事件) {
parent.requestDisallowInterceptTouchEvent(false);
}
break;
return super.dispatchTouchEvent(event);

这种方法的话父类容器需要默认拦截除了ACTION_DOWN以外的其他时间,这样当子元素调用request方法的时候父元素才能继续拦截所需的事件。

其他的 
      如果觉得上面两个方式太复杂,看晕了,其实也可以自己根据项目的实际需要来指定自己的策略实现。例如根据你手指按的点的位置来判断你当前触碰的是哪个控件,以此来猜测用户是否是要对这个控件进行操作。如果点击的是空白的地方,就操作外部控件即可。

,具体可参考ViewPager中的滑动冲突

Android中点击事件的处理解析及常见问题的更多相关文章

  1. Android中点击事件的四种写法详解

    Android中点击事件的四种写法 使用内部类实现点击事件 使用匿名内部类实现点击事件 让MainActivity实现View.OnClickListener接口 通过布局文件中控件的属性 第一种方法 ...

  2. Android中点击事件的实现方式

    在之前博文中多次使用了点击事件的处理实现,有朋友就问了,发现了很多按钮的点击实现,但有很多博文中使用的实现方式有都不一样,到底是怎么回事.今天我们就汇总一下点击事件的实现方式. 点击事件的实现大致分为 ...

  3. android中点击事件的4种写法

    android中获取到一些控件(比如说按钮)时,一般会为其添加点击事件,android中的点击事件一共有4中写法. 假设在布局文件中声明如下 ....... <Button android:la ...

  4. JS中点击事件冒泡阻止

    JS中点击事件冒泡阻止 解析: 一个div层'out',内含有一个div层'in'.如下: 两个层都绑定了点击事件,但是点击in层的时候,点击事件会出现冒泡现象,同时也会触发out层的点击事件. 但是 ...

  5. Android中点击隐藏软键盘最佳方法——Android开发之路4

    Android中点击隐藏软键盘最佳方法 实现功能:点击EditText,软键盘出现并且不会隐藏,点击或者触摸EditText以外的其他任何区域,软键盘被隐藏: 1.重写dispatchTouchEve ...

  6. Android点击事件(click button)的四种写法

    在学习android开发和测试的时候发现不同的人对于click事件的写法是不一样的,上网查了一下,发现有四种写法,于是想比较一下四种方法的不同 第一种方法:匿名内部类 代码: package com. ...

  7. Android点击事件

    Android点击事件 备注 全局实现View.OnClickListener 或许需要将MainActivity设置为public 注册事件 btn_login.setOnClickListener ...

  8. js for循环中点击事件中无法获取每一个i值的问题

    好像是第二次遇到这个问题,必须要总结一下!! <!DOCTYPE html> <html> <head> <meta charset="utf-8& ...

  9. android点击事件的四种方式

    android点击事件的四种方式 第一种方式:创建内部类实现点击事件 代码如下: package com.example.dail; import android.text.TextUtils; im ...

随机推荐

  1. HDU 5266 pog loves szh III(区间LCA)

    题目链接 pog loves szh III 题意就是  求一个区间所有点的$LCA$. 我们把$1$到$n$的$DFS$序全部求出来……然后设$i$的$DFS$序为$c[i]$,$pc[i]$为$c ...

  2. luogu P2746 [USACO5.3]校园网Network of Schools

    题目描述 一些学校连入一个电脑网络.那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”).注意即使 B 在 A 学校的分发列表中, A 也不一定在 B 学校的列表中. 你要写 ...

  3. 项目心得——按照指定的日期/时间创建Date对象

    项目心得——按照指定的日期/时间创建Date对象 有时,在做项目中,需要获得指定日期的Date对象,这个指定的日期或者时间可能不是当前的时间.下面讲解两种获取指定日期/时间的Date对象的方法: pa ...

  4. redis 延迟消息

    1.查询下redis 是否打开了键空间通知功能 发现打开了,如果没有打开可以在执行下 我们可以看到参数设置 2.订阅下键空间或者事件通知 订阅键空间:subscribe __keyspace@0__: ...

  5. Java出现错误“Invalid escape sequence (valid ones are \b \t \n \f \r \" \' \\ )”的问题分析

    若出现:Invalid escape sequence (valid ones are  \b  \t  \n  \f  \r  \"  \'  \\ )这样的问题,一般是转义字符的问题,下 ...

  6. iOS应用崩溃日志揭秘

    这篇文章还可以在这里找到 英语 Learn how to make sense of crash logs! 本文作者是 Soheil Moayedi Azarpour, 他是一名独立iOS开发者. ...

  7. Android(java方法)上实现mp4的分割和拼接 (二)

    这节谈一下如何在android上实现mp4文件的高效率切割. 业务需求举例:把一段2分钟的mp4文件切割出00:42 至 01:16这段时间的视频,要求足够短的执行时间和尽量少的误差. 分析:mp4P ...

  8. [反汇编练习] 160个CrackMe之036

    [反汇编练习] 160个CrackMe之036. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...

  9. 用 Sencha Touch 构建移动 web 应用程序

    Sencha Touch 是一个使用 HTML5.CSS3 和 JavaScript 语言构建的移动 web 应用程序框架,在本文中,学习如何应用您当前的 web 开发技能进行移动 web 开发.下载 ...

  10. vs2012编译ffmpeg

    从官方网站down下来的ffmpeg没有pdb文件不方便调试,为此使用VS2012编译ffmpeg. 编译步骤: 一.安装MinGW,具体的安装方法上一篇文章已经有介绍这里不在赘述. 二.下载文件并放 ...