Android Touch事件传递
touch翻译为接触,触摸。我们今天要聊的就是摸的事件。
在Android中了解了Touch事件可以帮助我们解决,ScrollView嵌套ListView,GridView,viewPager滑动冲突,还可以实现覆盖多层布局中里层某个控件的触摸事件处理(简单一点我理解的意思就是隔山打牛)等等,可能和你理解的有些偏差都是我在项目开发过程中总结而来的。针对以上问题,文章后面会给出解决方案。
什么是摸的事件,它们之间又是怎么传递的呢,请听我一一给你们道来。
什么是Android touch事件
就是触摸屏幕的一个过程,在Android中用户的Touch事件被包装成MotionEvent。
touch事件主要类型有:
- ACTION_DOWN: 表示用户开始触摸.
- ACTION_MOVE: 表示用户在移动(手指或者其他)
- ACTION_UP:表示用户抬起了手指
- ACTION_CANCEL:表示手势被取消了
- ACTION_OUTSIDE:表示用户触碰超出了正常的UI边界.
- ACTION_POINTER_DOWN:有一个非主要的手指按下了.
- ACTION_POINTER_UP:一个非主要的手指抬起来了
touch事件的元数据包括:
- touch的位置
- 手指的个数
- 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事件传递相关推荐
- Android Touch事件传递机制 二:单纯的(伪生命周期) 这个清楚一点
转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...
- Android Touch事件传递机制 二:单纯的(伪生命周期)
转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...
- Android Touch事件传递机制解析 (推荐)
最近新闻列表里的下拉 down up move 等等让我十分头疼 ,无意间看到了一篇非常不错的帖子,转载如下: 开篇语:最近程序在做一个小效果,要用到touch,结果整得云里面雾里的,干脆就好好把a ...
- android touch事件坐标原点,图解Android:Touch事件传递机制
前言 Android事件管理机制是一名专业Android研发工程师必须要了解的核心知识之一,深入了解一下该机制无论对我们日常开发还是找工作,乃至于对我们的架构思想都有很大的帮助.Android中我们用 ...
- Android Touch事件原理加实例分析
Android中有各种各样的事件,以响应用户的操作.这些事件可以分为按键事件和触屏事件.而Touch事件是触屏事件的基础事件,在进行Android开发时经常会用到,所以非常有必要深入理解它的原理机制. ...
- Android Touch事件分发—拦截—处理
Android Touch事件分发(dispatchTouchEvent)-拦截(onInterceptTouchEvent)-处理(onTouchEvent) 转自:http://www.cnblo ...
- android触摸屏事件,Android Touch事件分析
Android Touch事件分析 本文将分析Touch事件的传递.很多复杂的功能都需要深刻的处理Touch事件,例如侧边栏,例如图标的拖动换位. 一,Touch事件的执行轨迹 Down->Mo ...
- android touch事件无反应,触摸屏 无响应
(609条消息) android touch事件无反应,android的touch事件分发响应机制_蒙娜lisa的博客-CSDN博客 (609条消息) android touch事件无反应,移动端to ...
- Android触摸事件传递分析与实践
设计UI时,亲爱的交互设计师们总会有一些天马行空的想法,大多数情况下原生的控件已不能支持这些"看似简单"的交互逻辑,需要继承ListView.ViewPager.ScrollVie ...
最新文章
- 稀疏矩阵快速转置核心代码
- 用GAN还原语义标注图!还能手动改细节(附论文、代码)
- codeforces524E
- ThinkPHP集成万象优图
- Linux中ELF格式 可执行文件+动态链接器 的加载
- 光流法测试代码_高效的企业测试-工作流和代码质量(4/6)
- 69. x 的平方根 golang
- python小老鼠编程_成都python函数学习教程,Python编写课程
- nodejs返回html与vue,vuejs和nodejs的区别是什么?
- oracle安装实验,Oracle之课程实验一(安装oracle)
- python——语音信号读取、分帧、加窗
- 【笔记】时间片轮转 RR 进程调度算法(Java 实现)
- steam加速_追梦加速器:Steam一周销量前十榜单,你的游戏排第几?
- 通达OA与触点通RTC的集成插件
- 传输层 可靠传输 连续ARQ协议和滑动窗口协议
- 安装失败:user ‘system‘ has previously initiated an install for product‘‘
- leet55.跳跃游戏
- 大数据平台的开发与思考一:
- Pytorch系列笔记(二)
- C++游戏天堂——经典型(1)
热门文章
- k8s 查看 pod 网段
- python入门交流群_python 初学者交流 | Running Snail
- 环境设计与计算机表现,【环境艺术设计论文】环境艺术设计手绘表现技法分析(共2224字)...
- 运动耳机哪个牌子好性价比高,运动蓝牙耳机排行榜
- Java实战:Robot脚本自动写博客
- Win10系统问题解决——关键错误开始菜单和cortana无法工作
- 饥荒显示服务器未响应是什么意思,微软或将在本周内推送Win10 10586.71累积更新(图)...
- check_hostname requires server_hostname
- PAT [B1026 程序运行时间] C语言
- Java实现在线聊天