Hi,大家好,今天给大家分享一下Android中onInterceptTouchEvent与onTouchEvent,,记得楼主以前刚开始找工作的时候,被人问了关于Android中事件传递,当时还是菜鸟一枚,当然答不上来,被人无情的BS了。好了言归正传讲重点.

onInterceptTouchEvent:

onInterceptTouchEvent是在ViewGroup里面定义的。Android中的layout布局类一般都是继承此类的。onInterceptTouchEvent是用于拦截手势事件的,每个手势事件都会先调用onInterceptTouchEvent。

onTouchEvent:

onTouchEvent同样也是在view中定义的一个方法。处理传递到view 的手势事件。手势事件类型包括ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL等事件。

其中Layout里的onInterceptTouchEvent默认返回值是false,这样touch事件会传递到View控件,Layout里的onTouch默认返回值是false, View里的onTouch默认返回值是true,当我们手指点击屏幕时候,先调用ACTION_DOWN事件,当onTouch里返回值是true的时候,onTouch回继续调用ACTION_UP事件,如果onTouch里返回值是false,那么onTouch只会调用ACTION_DOWN而不调用ACTION_UP.

为了让当家更容易理解我写了一个简单的Demo.自定义了Layout与View,Android工程目录如下:

新建一个MyLayout.java代码如下:


[java] view plain copy
  1. packagecom.tutor.touch;
  2. importandroid.content.Context;
  3. importandroid.util.AttributeSet;
  4. importandroid.util.Log;
  5. importandroid.view.MotionEvent;
  6. importandroid.widget.FrameLayout;
  7. publicclassMyLayoutextendsFrameLayout{
  8. publicMyLayout(Contextcontext){
  9. super(context);
  10. }
  11. publicMyLayout(Contextcontext,AttributeSetattrs){
  12. super(context,attrs);
  13. //TODOAuto-generatedconstructorstub
  14. }
  15. @Override
  16. publicbooleanonInterceptTouchEvent(MotionEventev){
  17. Log.e(TouchDemoActivity.TAG,"MyLayoutonInterceptTouchEvent.");
  18. Log.e(TouchDemoActivity.TAG,"MyLayoutonInterceptTouchEventdefaultreturn"
  19. +super.onInterceptTouchEvent(ev));
  20. returnsuper.onInterceptTouchEvent(ev);
  21. }
  22. @Override
  23. publicbooleanonTouchEvent(MotionEventevent){
  24. Log.e(TouchDemoActivity.TAG,"MyLayoutonTouchEvent.");
  25. Log.e(TouchDemoActivity.TAG,"MyLayoutonTouchEventdefaultreturn"
  26. +super.onTouchEvent(event));
  27. returnsuper.onTouchEvent(event);
  28. }
  29. }

然后新建一个MyView.java代码如下:

[java] view plain copy
  1. packagecom.tutor.touch;
  2. importandroid.content.Context;
  3. importandroid.util.AttributeSet;
  4. importandroid.util.Log;
  5. importandroid.view.MotionEvent;
  6. importandroid.widget.Button;
  7. publicclassMyViewextendsButton{
  8. publicMyView(Contextcontext){
  9. super(context);
  10. }
  11. publicMyView(Contextcontext,AttributeSetattrs){
  12. super(context,attrs);
  13. }
  14. @Override
  15. publicbooleanonTouchEvent(MotionEventevent){
  16. Log.e(TouchDemoActivity.TAG,"MyViewonTouchEvent.");
  17. Log.e(TouchDemoActivity.TAG,"MyViewonTouchEventdefaultreturn"
  18. +super.onTouchEvent(event));
  19. returnsuper.onTouchEvent(event);
  20. }
  21. }

其中TouchDemoActivity代码如下:

[java] view plain copy
  1. packagecom.tutor.touch;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. publicclassTouchDemoActivityextendsActivity{
  5. publicstaticfinalStringTAG="TouchDemoActivity";
  6. @Override
  7. publicvoidonCreate(BundlesavedInstanceState){
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.main);
  10. }
  11. }

上面所有的布局文件main.xml代码如下:

[java] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <com.tutor.touch.MyLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. >
  6. <com.tutor.touch.MyView
  7. android:layout_width="fill_parent"
  8. android:layout_height="wrap_content"
  9. android:text="@string/hello"/>
  10. </com.tutor.touch.MyLayout>

运行上述Android工程效果如下:

点击红色区域,触发了MyView里的onTouch事件查看logcat,如下图:

点击绿色区域,则触发了MyLayout里的onTouch事件,查看logcat,如下图:

上面俩个截图都是用系统默认值,可以得出结论:onInterceptTouchEvent默认返回值是false,MyLayout里onTouchEvent默认返回值是false,所以只消费了ACTION_DOWN事件,MyView里onTouch默认返回值是true,调用了俩次:ACTION_DOW,ACTION_UP。

下面我们把MyLayout.java里的onInterceptTouchEvent的return值修改为true,代码如下:

[java] view plain copy
  1. @Override
  2. publicbooleanonInterceptTouchEvent(MotionEventev){
  3. Log.e(TouchDemoActivity.TAG,"MyLayoutonInterceptTouchEvent.");
  4. Log.e(TouchDemoActivity.TAG,"MyLayoutonInterceptTouchEventdefaultreturn"
  5. +super.onInterceptTouchEvent(ev));
  6. returntrue;
  7. }

运行工程,继续点击红色区域,查看logcat,发现MyView的onTouch事件没有被调用,也就是被拦截了如下图所示:

让我们继续实验,让onInterceptTouchEvent的返回值继续为false,将MyView里的onTouchEvent的返回值修改为false,即MyView里的onTouchEvent修改如下:

[java] view plain copy
  1. @Override
  2. publicbooleanonTouchEvent(MotionEventevent){
  3. Log.e(TouchDemoActivity.TAG,"MyViewonTouchEvent.");
  4. Log.e(TouchDemoActivity.TAG,"MyViewonTouchEventdefaultreturn"
  5. +super.onTouchEvent(event));
  6. returnfalse;
  7. }

运行工程,继续点击红色区域,查看logcat,如下图:

根据上图,我们可以看出MyView里的OnTouchEvent只消费了一次点击事件也就是ACTION_DOWN,还没有执行ACTION_UP,然后跑到MyLayout里又去执行了OnTouchEvent事件。

所以根据上面的内容总结如下:

ViewGroup里的onInterceptTouchEvent默认值是false这样才能把事件传给View里的onTouchEvent.

ViewGroup里的onTouchEvent默认值是false。

View里的onTouchEvent返回默认值是true.这样才能执行多次touch事件。

更多相关文章

  1. Android快速入门
  2. Android(安卓)Camera 使用小结
  3. Android(安卓)UI事件处理[isInTouchMode()]
  4. Your content must have a ListView whose id attribute is 'and
  5. android wifi
  6. [Android] AsyncTask使用实例---加载网络图片
  7. android SD卡文件监听
  8. 【Android(安卓)API】Android(安卓)4.1 API官方文档详解
  9. 关于Android四大基本组件介绍与生命周期

随机推荐

  1. 分享整理的12条sql语句连同数据
  2. Android(安卓)背景图片重复平铺
  3. Android(安卓)更新API详细
  4. 解决官网下载Android(安卓)Studio速度过
  5. android 概述 及四大组件
  6. Android手势左右滑动效果
  7. android TextView的字体颜色设置的多种方
  8. android上一些方法的区别和用法的注意事
  9. android:allowUndo
  10. android 圆形头像—— android开源系列:Ci