`
webcenterol
  • 浏览: 951047 次
文章分类
社区版块
存档分类
最新评论

Android: Android Touch事件处理

 
阅读更多

http://blog.csdn.net/iefreer/archive/2009/09/23/4586351.aspx

http://blog.csdn.net/ddna/archive/2010/04/11/5473293.aspx

http://blog.csdn.net/ddna/archive/2010/04/05/5451722.aspx

http://blog.csdn.net/G_rrrr/archive/2009/11/24/4861189.aspx

android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解。

一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP
当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?我只能很肯定的对你说不一定。呵呵,为什么呢?看看下面我的调查结果你就明白了。
android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev)这个方法用来分发TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent

当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, TouchEvent最先到达最顶层 view 的 dispatchTouchEvent ,然后由dispatchTouchEvent 方法进行分发,如果dispatchTouchEvent返回true ,则交给这个view的onTouchEvent处理,如果dispatchTouchEvent返回 false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。
通过语言描述这个处理逻辑很抽象,下面我就用代码来具体说明一下。
layout配置文件 main.xml
<?xml version="1.0" encoding="utf-8"?>
<test.lzqdiy.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center" >
<test.lzqdiy.MyTextView
android:layout_width="200px"
android:layout_height="200px"
android:id="@+id/tv"
android:text="lzqdiy"
android:textSize="40sp"
android:textStyle="bold"
android:background="#FFFFFF"
android:textColor="#0000FF"/>
</test.lzqdiy.MyLinearLayout>
节点层次很简单,一个LinearLayout中添加了一个TextView。
下面是java代码:
package test.lzqdiy;

import android.app.Activity;
import android.os.Bundle;

public class TestTouchEventApp extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
package test.lzqdiy;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class MyLinearLayout extends LinearLayout {
private final String TAG = "MyLinearLayout";

public MyLinearLayout(Context context, AttributeSet attrs) {

super(context, attrs);

Log.d(TAG, TAG);

}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int action = ev.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

Log.d(TAG, "dispatchTouchEvent action:ACTION_DOWN");

break;

case MotionEvent.ACTION_MOVE:

Log.d(TAG, "dispatchTouchEvent action:ACTION_MOVE");

break;

case MotionEvent.ACTION_UP:

Log.d(TAG, "dispatchTouchEvent action:ACTION_UP");

break;

case MotionEvent.ACTION_CANCEL:

Log.d(TAG, "dispatchTouchEvent action:ACTION_CANCEL");

break;

}
return super.dispatchTouchEvent(ev);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {

int action = ev.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

Log.d(TAG, "onInterceptTouchEvent action:ACTION_DOWN");

break;

case MotionEvent.ACTION_MOVE:

Log.d(TAG, "onInterceptTouchEvent action:ACTION_MOVE");

break;

case MotionEvent.ACTION_UP:

Log.d(TAG, "onInterceptTouchEvent action:ACTION_UP");

break;

case MotionEvent.ACTION_CANCEL:

Log.d(TAG, "onInterceptTouchEvent action:ACTION_CANCEL");

break;

}

return false;

}

@Override
public boolean onTouchEvent(MotionEvent ev) {

int action = ev.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

Log.d(TAG, "---onTouchEvent action:ACTION_DOWN");

break;

case MotionEvent.ACTION_MOVE:

Log.d(TAG, "---onTouchEvent action:ACTION_MOVE");

break;

case MotionEvent.ACTION_UP:

Log.d(TAG, "---onTouchEvent action:ACTION_UP");

break;

case MotionEvent.ACTION_CANCEL:

Log.d(TAG, "---onTouchEvent action:ACTION_CANCEL");

break;

}

return true;
}

}

package test.lzqdiy;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;

public class MyTextView extends TextView {

private final String TAG = "MyTextView";

public MyTextView(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int action = ev.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

Log.d(TAG, "dispatchTouchEvent action:ACTION_DOWN");

break;

case MotionEvent.ACTION_MOVE:

Log.d(TAG, "dispatchTouchEvent action:ACTION_MOVE");

break;

case MotionEvent.ACTION_UP:

Log.d(TAG, "dispatchTouchEvent action:ACTION_UP");

break;

case MotionEvent.ACTION_CANCEL:

Log.d(TAG, "onTouchEvent action:ACTION_CANCEL");

break;

}
return super.dispatchTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {

int action = ev.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

Log.d(TAG, "---onTouchEvent action:ACTION_DOWN");

break;

case MotionEvent.ACTION_MOVE:

Log.d(TAG, "---onTouchEvent action:ACTION_MOVE");

break;

case MotionEvent.ACTION_UP:

Log.d(TAG, "---onTouchEvent action:ACTION_UP");

break;

case MotionEvent.ACTION_CANCEL:

Log.d(TAG, "---onTouchEvent action:ACTION_CANCEL");

break;

}

return true;

}

}

为了指代方便,下面将MyLinearLayout简称为L,将MyTextView简称为T,L.onInterceptTouchEvent=true 表示的含义为MyLinearLayout中的onInterceptTouchEvent方法返回值为true,通过程序运行时输出的Log来说明调用时序。
第1种情况 L.onInterceptTouchEvent=false&& L.onTouchEvent=true &&T.onTouchEvent=true 输出下面的Log:
D/MyLinearLayout(11865): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(11865): onInterceptTouchEvent action:ACTION_DOWN
D/MyTextView(11865): dispatchTouchEvent action:ACTION_DOWN
D/MyTextView(11865): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(11865): dispatchTouchEvent action:ACTION_MOVE
D/MyLinearLayout(11865): onInterceptTouchEvent action:ACTION_MOVE
D/MyTextView(11865): dispatchTouchEvent action:ACTION_MOVE
D/MyTextView(11865): ---onTouchEvent action:ACTION_MOVE
...........省略其他的ACTION_MOVE事件Log
D/MyLinearLayout(11865): dispatchTouchEvent action:ACTION_UP
D/MyLinearLayout(11865): onInterceptTouchEvent action:ACTION_UP
D/MyTextView(11865): dispatchTouchEvent action:ACTION_UP
D/MyTextView(11865): ---onTouchEvent action:ACTION_UP
结论:TouchEvent完全由TextView处理。
第2种情况L.onInterceptTouchEvent=false&& L.onTouchEvent=true &&T.onTouchEvent=false 输出下面的Log:
D/MyLinearLayout(13101): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13101): onInterceptTouchEvent action:ACTION_DOWN
D/MyTextView(13101): dispatchTouchEvent action:ACTION_DOWN
D/MyTextView(13101): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13101): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13101): dispatchTouchEvent action:ACTION_MOVE
D/MyLinearLayout(13101): ---onTouchEvent action:ACTION_MOVE
...........省略其他的ACTION_MOVE事件Log
D/MyLinearLayout(13101): dispatchTouchEvent action:ACTION_UP
D/MyLinearLayout(13101): ---onTouchEvent action:ACTION_UP
结论:TextView只处理了ACTION_DOWN事件,LinearLayout处理了所有的TouchEvent。
第3种情况L.onInterceptTouchEvent=true&& L.onTouchEvent=true 输出下面的Log:
D/MyLinearLayout(13334): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13334): onInterceptTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13334): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13334): dispatchTouchEvent action:ACTION_MOVE
D/MyLinearLayout(13334): ---onTouchEvent action:ACTION_MOVE
...........省略其他的ACTION_MOVE事件Log
D/MyLinearLayout(13334): dispatchTouchEvent action:ACTION_UP
D/MyLinearLayout(13334): ---onTouchEvent action:ACTION_UP
结论:LinearLayout处理了所有的TouchEvent。
第4种情况L.onInterceptTouchEvent=true&& L.onTouchEvent=false 输出下面的Log:
D/MyLinearLayout(13452): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13452): onInterceptTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13452): ---onTouchEvent action:ACTION_DOWN
结论:LinearLayout只处理了ACTION_DOWN事件,那么其他的TouchEvent被谁处理了呢?答案是LinearLayout最外层的Activity处理了TouchEvent。
分享到:
评论

相关推荐

    android之Touch事件处理机制测试

    本文将深入探讨“android之Touch事件处理机制测试”,包括滑动事件冲突的解决、ViewGroup中的事件触发和传递机制。 一、Android Touch事件处理机制 1. 触摸事件流程:在Android中,触摸事件分为三个阶段,即ACTION...

    Android Touch事件传递机制解析

    在Android系统中,触摸事件(Touch Event)是用户与设备交互的重要方式,它涉及到了UI控件的响应和处理。本文将深入解析Android的Touch事件传递机制,帮助开发者理解这一核心概念。 首先,我们了解下Android中的...

    Android中Touch事件的传递

    Android中的Touch事件传递是一个涉及多个组件和层次的过程。为了深刻理解这一过程,我们首先需要了解Activity...通过理解这些机制,开发者可以编写出更加合理和高效的事件处理代码,以优化用户界面的响应性和交互性。

    android Touch事件传递机制

    本文将深入探讨Android的触摸事件处理流程,包括事件的产生、分发以及处理过程,以实例的形式帮助开发者理解这一核心概念。 ### 一、事件产生 当用户在屏幕上触摸时,硬件层会生成原始的触控事件(MotionEvent),...

    Android深入研究Touch事件demo

    本篇将深入探讨Android中的触摸事件处理,包括事件的产生、分发、拦截以及如何自定义触摸行为。 一、事件流概述 在Android中,触摸事件遵循一个特定的顺序,即`ACTION_DOWN -&gt; ACTION_MOVE -&gt; ACTION_UP/ACTION_...

    android测试Touch事件DEMO

    本DEMO主要目的是帮助开发者理解并测试Android中的触摸事件处理机制。 Android的触摸事件处理主要包括三个基本动作:ACTION_DOWN(按下)、ACTION_MOVE(移动)和ACTION_UP(释放)。当用户触摸屏幕时,系统会生成...

    Android-ForceTouch在Android中的简单实现

    **Android-ForceTouch在Android中的简单实现** Force Touch技术,起源于Apple的iPhone,并逐渐被引入到Android系统中,为用户界面带来了全新的交互体验。它能够感知用户触摸屏幕时的压力变化,通过不同的按压力度来...

    Android Touch事件分发机制代码一

    5. **自定义视图的事件处理** 在开发过程中,我们有时需要自定义View或ViewGroup以实现特定的交互效果。这时,可以利用事件分发机制,通过重写onInterceptTouchEvent()和onTouchEvent()来控制事件的流向和处理方式...

    Android Touch事件rawX,rawY与x,y的区别

    在Android开发中,触摸事件(Touch Events)是用户与设备交互的重要部分,特别是涉及到界面的交互操作时。本文将深入探讨Android Touch事件中`...开发者应根据具体需求选择合适的坐标属性,以实现精确的触摸事件处理。

    Android判断touch事件点是否在view范围内的方法

    首先,让我们了解Android中的触摸事件处理流程。Android通过MotionEvent类来表示触摸屏幕产生的动作,如ACTION_DOWN、ACTION_UP、ACTION_MOVE等。当用户触摸屏幕时,系统会生成一个MotionEvent对象,并将其传递给...

    Pro Android学习:touch screen小例子

    在这个实例中,我们将深入探讨Android的触摸事件处理机制以及如何编写源代码来实现基本的手势识别。 首先,Android的触摸事件处理主要通过View和 ViewGroup的触摸事件回调方法进行。这些方法包括`onTouchEvent...

    Android 编程下 Touch 事件的分发和消费机制

    Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev);能够响应这些方法的控件包括:ViewGroup、View、Activity。...

    android soundtouch demo

    2. **关键API**:例如`soundtouch::SoundTouch`类是主要的处理对象,`setSampleRate()`、`setChannels()`和`setTempoChange()`等方法用于配置处理参数。 3. **音频流处理**:通过`putSamples()`将原始音频数据送入...

    android touch事件解析

    测试过程自己重载了Testlinearlayout 继承自 linearLayout ,里面包含了一个重载的TestButton继承自Button

    android touch demo

    `android touch demo`是一个用于演示Android系统中触摸事件处理的示例项目,通过这个项目,我们可以深入理解Android触摸事件的工作原理以及如何在应用中实现对触摸事件的响应。 触摸事件主要由三类基本事件组成:...

    android touch事件及触屏简单的应用

    本篇主要介绍Android中的触摸事件处理机制以及如何实现一个简单的触屏画图应用。 Android的触摸事件处理主要通过View类的onTouchEvent()方法来完成。当用户在屏幕上进行触摸操作时,系统会生成一系列的MotionEvent...

    android input 事件的获取

    InputDispatcher 负责将事件分发给应用程序,流程解析可以分为两个阶段:事件分发和事件处理。在事件分发阶段,InputDispatcher 会将事件传递给应用程序。在事件处理阶段,应用程序会处理事件,并对事件进行响应。 ...

    Android基础篇-Button学习

    在布局文件中,Button可以使用`android:onClick`属性直接指定点击事件的处理方法。例如: ```xml android:id="@+id/myButton" android:layout_width="wrap_content" android:layout_height="wrap_content" ...

    android4.0 input touch分析

    * InputManager:InputManager 是系统事件处理的核心,管理所有输入设备的事件处理工作。InputManager 使用两个线程:InputReaderThread 和 DispatcherThread。 Linux 内核层 在 Linux 内核层,输入触摸流程主要...

Global site tag (gtag.js) - Google Analytics