touch翻译为接触,触摸。我们今天要聊的就是摸的事件。

在Android中了解了Touch事件可以帮助我们解决,ScrollView嵌套ListView,GridView,viewPager滑动冲突,还可以实现覆盖多层布局中里层某个控件的触摸事件处理(简单一点我理解的意思就是隔山打牛)等等,可能和你理解的有些偏差都是我在项目开发过程中总结而来的。针对以上问题,文章后面会给出解决方案。

什么是摸的事件,它们之间又是怎么传递的呢,请听我一一给你们道来。

什么是Android touch事件

就是触摸屏幕的一个过程,在Android中用户的Touch事件被包装成MotionEvent。

touch事件主要类型有:

  1. ACTION_DOWN: 表示用户开始触摸.
  2. ACTION_MOVE: 表示用户在移动(手指或者其他)
  3. ACTION_UP:表示用户抬起了手指
  4. ACTION_CANCEL:表示手势被取消了
  5. ACTION_OUTSIDE:表示用户触碰超出了正常的UI边界.
  6. ACTION_POINTER_DOWN:有一个非主要的手指按下了.
  7. ACTION_POINTER_UP:一个非主要的手指抬起来了

touch事件的元数据包括:

  1. touch的位置
  2. 手指的个数
  3. touch事件的时间

当然一个touch手势被定义为以ACTION_DOWN开始和以 ACTION_UP结束。

事件传递

Android 中与 Touch 事件相关的三个方法

1、​public boolean dispatchTouchEvent(MotionEvent ev),这个方法是用来分发事件处理。

2、​public boolean onInterceptTouchEvent(MotionEvent ev) ,这个方法是用来拦截,截断事件处理。

3、public boolean onTouchEvent(MotionEvent ev),这个方法是用来处理事件。

能够响应、调用以上方法的有ViewGroup、View、Activity,继承ViewGroup的控件大多是容器控件,如LinearLayout,RelativeLayout等。继承View的控件大多是显示控件,如TextView,Button等。

需要注意的是显示控件是没有onInterceptTouchEvent方法。

上面我们具体来看一个案例,来了解事件是怎么传递的:

上图的.xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><com.github.ws.touchdemo.MyRelativeLayout1android:layout_width="280dp"android:layout_height="280dp"android:layout_centerInParent="true"android:background="#f00000"><com.github.ws.touchdemo.MyRelativeLayout2android:layout_width="180dp"android:layout_height="180dp"android:layout_centerInParent="true"android:background="#00f000"><com.github.ws.touchdemo.MyTextViewandroid:layout_width="80dp"android:layout_height="80dp"android:layout_centerInParent="true"android:background="#0000f0" /></com.github.ws.touchdemo.MyRelativeLayout2></com.github.ws.touchdemo.MyRelativeLayout1></RelativeLayout>

MyRelativeLayout1

package com.github.ws.touchdemo;import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.RelativeLayout;/*** Created by Administrator on 3/9 0009.*/
public class MyRelativeLayout1 extends RelativeLayout {public MyRelativeLayout1(Context context) {super(context);}public MyRelativeLayout1(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {Log.e("------MyRelativeLayout1----", "--------dispatchTouchEvent------");return super.dispatchTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent event) {Log.e("------MyRelativeLayout1----", "--------onTouchEvent------");return super.onTouchEvent(event);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {Log.e("------MyRelativeLayout1----", "--------onInterceptTouchEvent------");return super.onInterceptTouchEvent(ev);}
}

MyRelativeLayout2和MyRelativeLayout1一样。

MyTextView

package com.github.ws.touchdemo;import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;/*** Created by Administrator on 3/9 0009.*/
public class MyTextView extends TextView {public MyTextView(Context context, AttributeSet attrs) {super(context, attrs);}public MyTextView(Context context) {super(context);}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {Log.e("------MyTextView----", "--------dispatchTouchEvent------");return super.dispatchTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent event) {Log.e("------MyTextView----", "--------onTouchEvent------");return super.onTouchEvent(event);}}

当我们触摸蓝色区域Log打印如下:

通过log图,我们很容易的得出结论:dispatchTouchEvent(),onInterceptTouchEvent()隧道式向下分发(先里后外)。而onTouchEvent()执行顺序恰好相反即冒泡式向上处理(先外后里)。

我们来改变touch方法的返回值,看看它们又是怎么执行的。

MyRelativeLayout1类中dispatchTouchEvent返回true

我直接贴log:

很明显事件并不会向外分发,后面的事件不会触发,默认返回false。

MyRelativeLayout1类中onInterceptTouchEvent返回true

onInterceptTouchEvent()用于处理事件并改变事件的传递方向。处理事件就是在函数内部编写代码处理就可以了。而决定传递方向的是返回值,返回为false时事件会传递给子控件的dispatchTouchEvent();返回值为true时事件会传递给当前控件的onTouchEvent(),不会传递给子控件,这就是所谓的Intercept(拦截,截断)。默认返回false。

MyRelativeLayout1类中onTouchEvent返回true

我们在onTouchEvent中添加如下代码:

 switch (event.getAction()) {case MotionEvent.ACTION_DOWN:Log.e("-------MyRelativeLayout1---------", "--------ACTION_DOWN------");break;case MotionEvent.ACTION_MOVE:Log.e("--------MyRelativeLayout1--------", "--------ACTION_MOVE------");break;}

贴出log:

onTouchEvent() 用于处理事件,返回值决定当前控件是否消费了这个事件。如果返回值为true表示消费了这个事件,那么系统就会认为ACTION_DOWN已经发生,ACTION_MOVE或者ACTION_UP就被捕获。反之,ACTION_MOVE或者ACTION_UP就不会被捕获。默认是返回false。(ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN)。

看到这里,我相信大家对事件传递有了自己的认识,我给出开头滑动冲突的解决方案:

 mScrollView.requestDisallowInterceptTouchEvent(true);

一张图来诠释 Android Touch 事件传递:

如果你有兴趣查看源码,请点击github地址

Android Touch事件传递相关推荐

  1. Android Touch事件传递机制 二:单纯的(伪生命周期) 这个清楚一点

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  2. Android Touch事件传递机制 二:单纯的(伪生命周期)

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  3. Android Touch事件传递机制解析 (推荐)

    最近新闻列表里的下拉 down up  move 等等让我十分头疼 ,无意间看到了一篇非常不错的帖子,转载如下: 开篇语:最近程序在做一个小效果,要用到touch,结果整得云里面雾里的,干脆就好好把a ...

  4. android touch事件坐标原点,图解Android:Touch事件传递机制

    前言 Android事件管理机制是一名专业Android研发工程师必须要了解的核心知识之一,深入了解一下该机制无论对我们日常开发还是找工作,乃至于对我们的架构思想都有很大的帮助.Android中我们用 ...

  5. Android Touch事件原理加实例分析

    Android中有各种各样的事件,以响应用户的操作.这些事件可以分为按键事件和触屏事件.而Touch事件是触屏事件的基础事件,在进行Android开发时经常会用到,所以非常有必要深入理解它的原理机制. ...

  6. Android Touch事件分发—拦截—处理

    Android Touch事件分发(dispatchTouchEvent)-拦截(onInterceptTouchEvent)-处理(onTouchEvent) 转自:http://www.cnblo ...

  7. android触摸屏事件,Android Touch事件分析

    Android Touch事件分析 本文将分析Touch事件的传递.很多复杂的功能都需要深刻的处理Touch事件,例如侧边栏,例如图标的拖动换位. 一,Touch事件的执行轨迹 Down->Mo ...

  8. android touch事件无反应,触摸屏 无响应

    (609条消息) android touch事件无反应,android的touch事件分发响应机制_蒙娜lisa的博客-CSDN博客 (609条消息) android touch事件无反应,移动端to ...

  9. Android触摸事件传递分析与实践

    设计UI时,亲爱的交互设计师们总会有一些天马行空的想法,大多数情况下原生的控件已不能支持这些"看似简单"的交互逻辑,需要继承ListView.ViewPager.ScrollVie ...

最新文章

  1. 稀疏矩阵快速转置核心代码
  2. 用GAN还原语义标注图!还能手动改细节(附论文、代码)
  3. codeforces524E
  4. ThinkPHP集成万象优图
  5. Linux中ELF格式 可执行文件+动态链接器 的加载
  6. 光流法测试代码_高效的企业测试-工作流和代码质量(4/6)
  7. 69. x 的平方根 golang
  8. python小老鼠编程_成都python函数学习教程,Python编写课程
  9. nodejs返回html与vue,vuejs和nodejs的区别是什么?
  10. oracle安装实验,Oracle之课程实验一(安装oracle)
  11. python——语音信号读取、分帧、加窗
  12. 【笔记】时间片轮转 RR 进程调度算法(Java 实现)
  13. steam加速_追梦加速器:Steam一周销量前十榜单,你的游戏排第几?
  14. 通达OA与触点通RTC的集成插件
  15. 传输层 可靠传输 连续ARQ协议和滑动窗口协议
  16. 安装失败:user ‘system‘ has previously initiated an install for product‘‘
  17. leet55.跳跃游戏
  18. 大数据平台的开发与思考一:
  19. Pytorch系列笔记(二)
  20. C++游戏天堂——经典型(1)

热门文章

  1. k8s 查看 pod 网段
  2. python入门交流群_python 初学者交流 | Running Snail
  3. 环境设计与计算机表现,【环境艺术设计论文】环境艺术设计手绘表现技法分析(共2224字)...
  4. 运动耳机哪个牌子好性价比高,运动蓝牙耳机排行榜
  5. Java实战:Robot脚本自动写博客
  6. Win10系统问题解决——关键错误开始菜单和cortana无法工作
  7. 饥荒显示服务器未响应是什么意思,微软或将在本周内推送Win10 10586.71累积更新(图)...
  8. check_hostname requires server_hostname
  9. PAT [B1026 程序运行时间] C语言
  10. Java实现在线聊天