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。

更多相关文章

  1. 解决ListView的ItemView中带有Button时,OnItemClick无效的问题
  2. Android中activity触摸操作dispatchTouchEvent
  3. ant编译android工程用批处理打包
  4. android 事件处理机制
  5. Android带返回值的窗口跳转
  6. android bitmap 处理
  7. Android事件处理
  8. Android横竖屏切换解决方案
  9. android 开启本地相册选择图片并返回显示

随机推荐

  1. Tabhost
  2. 更新Anadroid SDK Tooks之后,Eclipse提示N
  3. ScrollView 嵌套 RecyclerView 显示不完
  4. Android(安卓)再按一次退出程序三种办法
  5. Android(安卓)-- 过滤器相关
  6. 第一个Android程序--Hello Android
  7. android 界面布局
  8. Android系统架构
  9. 丢失Android系统库或者Conversion to Dal
  10. android camera(四):camera 驱动 GT2005