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 >


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM