android onTouchEvent处理机制总结

项目中总会用到一些触摸事件,每次使用都是百度各种资料,看各种大神的分析笔记。这次我自己总结下关于触摸事件的一些知识点。一来可以让自己对触摸事件印象更加深刻,也给以后的项目做一个参考。最难理解的其实是onTouchEvent方法。

 
一. 概述
1.只有view,ViewGroup,Activity 具有事件分发和消费的功能。
2.Activity因为上最先接触到触摸事件,因此Activity没有事件拦截方法。即没有dispatchTouchEvent方法。
3.对于不能添加子控件的view,不能对事件进行分发和拦截,它只有onTouchEvent事件。
 
二.三个方法
1. public  boolean  dispatchTouchEvent(MotionEvent  ev )
当触摸事件发生的时候,首先会被当前的activity进行分发,即当前activity的dispatchTouchEvent方法会被执行。
这个时候,该方法有三种返回的情况:
          return false: 表明事件不会被进行分发。事件会以冒泡的方式被传递给上层的view或activity的onTouchEvent方法进行消费掉。
          return true:表明该时间已经被处理。事件会被当前view或activity的dispatchTouchEvent给消费掉。不会再进行传递,事件到此结束。
          return super.dispatchTouchEvent(ev):表明该事件将会被分发。此时当前View的onIntercepterTouchEvent方法会捕获该事件,判断需不需要进行事件的拦截。
 
2. public  boolean  onInterceptTouchEvent(MotionEvent  ev )     
该方法用户拦截被传递过来的事件,用于判断被传递过来的事件是否需要被当前的view进行处理。
     return false : 不对事件进行拦截,放行该事件。事件会被传递到当前view的子控件中,由子控件中的dispatchTouchEvent方法进行分发处理。
     return true : 拦截该事件,将该事件交给当前view的onTouchEvent方法进行处理。
     return super.inInterceptTouchEvent(ev):默认拦截方式,和return true一样。该事件会被拦截,将该事件交给当前view的onTouchEvent方法进行处理。(这里需要有一点说明,当有两个view。A view中有一个B view.点击A.A中如果onInterceptTouchEvent()返回super.interceptTouchEvent(ev),则事件将会被A进行拦截,交给A的onTouchEvent()进行处理,如果点击的是B,A中如果onInterceptTouchEvent()返回super.interceptTouchEvent(ev),则事件将不会被拦截,会被分发到子控件中)
 
3. public  boolean  onTouchEvent(MotionEvent  event )
当前的view把事件进行了拦截,则事件则会被传递到该方法中
     return false:表明没有消费该事件,事件将会以冒泡的方式一直被传递到上层的view或Activity中的onTouchEvent事件处理。如果最上层的view或Activity中的onTouchEvent还是返回false。则该事件将消失。接下来来的一系列事件都将会直接被上层的onTouchEvent方法捕获
     return true: 表明消费了该事件,事件到此结束。
     return super.onTouchEvent(event):默认情况,和return false一样。
 
验证:
MainActivity FatherView ChildView中几个方法都返回super.****TouchEvent(ev)
     分析:
  1. 当点击屏幕。MainActivity 中的dispatchTouchEvent方法先执行,打印MainActivity-dispatchTouchEvent-->ACTION_DOWN
  2. 因为返回的是super.dispatchTouchEvent(ev),所以事件ev将会被分发,但是MainActivity中没有onInterceptTouchEvent()方法,所以事件被传递到FatherView中的dispatchTouchEvent方法.打印FatherView-dispatchTouchEvent-->ACTION_DOWN
  3. 在FatherView中dispatchTouchEvent返回的是super.dispatchTouchEvent(ev),所有事件会被分发。FatherView中的onInterceptTouchEven()中的方法被执行。打印FatherView-onInterceptTouchEven-->ACTION_DOWN
  4. FatherView中的onInterceptTouchEven()返回的是super.onInterceptTouchEvent(ev)。在这里,(1)如果点击的是屏幕中的ChildView。事件将不会被拦截,会被传递到ChildView中的dispatchTouchEvent方法中。(2)如果点击的值FatherView则事件将会被拦截。FatherView中的onTouchEvent()方法将被执行。以(1)为例,将打印ChildView-dispatchTouchEvent-->ACTION_DOWN。
  5. ChildView中dispatchTouchEvent返回的是super.dispatchTouchEvent(ev),所有事件会被分发。打印ChildView-onInterceptTouchEvent-->ACTION_DOWN。
  6. 此时ChildView中onInterceptTouchEvent返回的是super.onInterceptTouchEvent(ev),,而且已经没有子控件了,所以事件将被拦截。打印ChildView-onTouchEvent-->ACTION_DOWN。
  7. 在childView中onTouchEvent()返回额是super.onTouchEvent(ev)。事件将不会被消耗,将以冒泡的方式传递到上层空间中的onTouchEvent(),此处上层空间中的onTouchEvent返回的都是super.onTouchEvent(ev)。所以讲一次打印 Father-onTouchEvent-->ACTION_DOWN。 MainActivty-onTouchEvent-->ACTION_DOWN。
  8. 之后的事件动作,将不再被MainActivity分发到子view,直接被MainActivty中的onTouchEvent处理消耗。打印MainActivity-dispatchTouchEvent-->ACTION_UP,MainActivty-onTouchEvent-->ACTION_UP
            MainActivity-dispatchTouchEvent-->ACTION_DOWN
            FatherView-dispatchTouchEvent-->ACTION_DOWN
            FatherView-onInterceptTouchEven-->ACTION_DOWN
            ChildView-dispatchTouchEvent-->ACTION_DOWN
            ChildView-onInterceptTouchEvent-->ACTION_DOWN。
            ChildView-onTouchEvent-->ACTION_DOWN
            Father-onTouchEvent-->ACTION_DOWN。 
            MainActivty-onTouchEvent-->ACTION_DOWN
            MainActivity-dispatchTouchEvent-->ACTION_UP,
            MainActivty-onTouchEvent-->ACTION_UP
               
 
代码
MainActivity.java
public  class  MainActivity  extends  Activity {
 
      private  static  final  String  TAG  =  "MainActivity" ;
 
      @Override
      protected  void  onCreate(Bundle  savedInstanceState ) {
             super .onCreate(  savedInstanceState );
           setContentView(R.layout.  activity_main );
     }
 
      @Override
      public  boolean  onTouchEvent(MotionEvent  event ) {
             //  TODO  Auto-generated method stub
           Log. i( TAG ,  "activity-onTouchEvent-->"  + TouchEventUtil.getTouchAction( event .getAction()));
             return  super .onTouchEvent(  event );
     }
 
      @Override
      public  boolean  dispatchTouchEvent(MotionEvent  ev ) {
           Log. i( TAG ,  "activity-dispatchTouchEvent-->"  + TouchEventUtil.getTouchAction( ev .getAction()));
             return  super .dispatchTouchEvent(  ev );
     }
 
FatherView.java
      public  class  FatherView  extends  LinearLayout {
      private  static  final  String  TAG  =  "MainActivity" ;
 
      public  FatherView(Context  context ) {
             super (  context );
 
     }
 
      @Override
      public  boolean  dispatchTouchEvent(MotionEvent  ev ) {
           Log. i( TAG ,  "Father-dispatchTouchEvent-->"  + TouchEventUtil.getTouchAction( ev .getAction()));
             return  super .dispatchTouchEvent(  ev );
     }
 
      @Override
      public  boolean  onInterceptTouchEvent(MotionEvent  ev ) {
           Log. i( TAG ,  "Father-onInterceptTouchEvent-->"  + TouchEventUtil.getTouchAction( ev .getAction()));
             return  super .onInterceptTouchEvent(  ev );
     }
 
      @Override
      public  boolean  onTouchEvent(MotionEvent  event  ) {
           Log. i( TAG ,  "Father-onTouchEvent-->"  + TouchEventUtil.getTouchAction( event .getAction()));
             return  super .onTouchEvent(  event );
     }
 
}
 
ChildView.java
public  class  ChildView  extends  LinearLayout {
 
      private  static  final  String  TAG  =  "MainActivity" ;
 
      public  ChildView(Context  context ) {
             super (  context );
     }
 
      @Override
      public  boolean  dispatchTouchEvent(MotionEvent  ev ) {
           Log. i( TAG ,  "Child-dispatchTouchEvent-->"  + TouchEventUtil.getTouchAction( ev .getAction()));
             return  super .dispatchTouchEvent(  ev );
     }
 
      @Override
      public  boolean  onInterceptTouchEvent(MotionEvent  ev ) {
           Log. i( TAG ,  "Child-onInterceptTouchEvent-->"  + TouchEventUtil.getTouchAction( ev .getAction()));
             return  super .onInterceptTouchEvent(  ev );
     }
 
      @Override
      public  boolean  onTouchEvent(MotionEvent  event  ) {
           Log. i( TAG ,  "Child-onTouchEvent-->"  + TouchEventUtil.getTouchAction( event .getAction()));
             return  super .onTouchEvent(  event );
     }
 
}
 
activity_main.xml
< RelativeLayout  xmlns:android = "http://schemas.android.com/apk/res/android"
     xmlns:tools = "http://schemas.android.com/tools"
     android:layout_width =  "match_parent"
     android:layout_height =  "match_parent"
     tools:context = "${relativePackage}.${activityClass}"  >
 
     < com.ethanlbb.toucheventtest.FatherView
         android:layout_width =  "match_parent"
         android:layout_height =  "match_parent"
         android:background =  "@android:color/holo_blue_dark"
         android:gravity =  "center"  >
 
         < com.ethanlbb.toucheventtest.ChildView
             android:layout_width =  "200dp"
             android:layout_height =  "200dp"
             android:layout_gravity =  "center"
             android:background =  "#0000ff"  >
         </ com.ethanlbb.toucheventtest.ChildView  >
     </ com.ethanlbb.toucheventtest.FatherView  >
 
</ RelativeLayout >

转载于:https://www.cnblogs.com/ethanlee/p/4073979.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值