onInterceptTouchEvent 와 onTouchEvent 호출 순서

<?xml version="1.0" encoding="utf-8"?>

<com.touchstudy.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent" >

    <com.touchstudy.LayoutView2

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:gravity="center">

       <com.touchstudy.MyTextView 

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:id="@+id/tv"

            android:text="AB"

            android:textSize="40sp"

            android:textStyle="bold"

            android:background="#FFFFFF"

            android:textColor="#0000FF"/>

   </com.touchstudy.LayoutView2>

</com.touchstudy.LayoutView1>
 
onInterceptTouchEvent()는 ViewGroup 의 한 방법 으로 시스템 이 이 ViewGroup 과 그 각 childView 에 onTouchEvent()를 촉발 하기 전에 관련 사건 을 차단 하 는 것 이 목적 이다.Android 는 이렇게 디자인 한 생각 도 잘 이해 할 수 있다.ViewGroup 은 약간의 childView 를 포함 하기 때문에 각종 touch 사건 을 통일 적 으로 감시 할 수 있 는 기회 가 필요 하 다.따라서 순수 하 게 하위 view 를 포함 할 수 없 는 컨트롤 은 이 방법 이 없습니다.예 를 들 어 LinearLayout 에 있 으 면 TextView 에 없습니다. 
onInterceptTouchEvent()사용 도 간단 합 니 다.View Group 에 이 방법 을 복사 하면 각종 touch 사건 을 차단 할 수 있 습 니 다.그러나 어떻게 차단 하 는 지,모든 touch 사건 을 차단 해 야 하 는 지 여 부 는 비교적 복잡 하 다.touch 사건 은 onInterceptTouchEvent()와 onTouchEvent 및 각 childView 간 의 전달 체 제 는 onInterceptTouchEvent()와 onTouchEvent()의 반환 값 에 달 려 있다.또한 다운 이벤트 처리 에 대한 반환 값 은 후속 move 와 up 이벤트 의 수신 과 전달 에 직접적인 영향 을 미친다. 
반환 값 에 대한 문 제 는 기본 규칙 이 분명 합 니 다.return true 라면 이 방법 이 이번 사건 을 소 비 했 음 을 나타 냅 니 다.return false 라면 이 방법 이 완전히 처리 되 지 않 았 음 을 나타 내 고 이 사건 은 어떤 방식 으로 전달 되 어 계속 처 리 를 기 다 려 야 합 니 다.
SDK 가 제시 한 설명 은 다음 과 같다.
·    You will receive the down event here.
·    The down event will be handled either by a child of this view group, or given to your own onTouchEvent() method to handle; this means you should implement onTouchEvent() to return true, so you will continue to see the rest of the gesture (instead of looking for a parent view to handle it). Also, by returning true from onTouchEvent(), you will not receive any following events in onInterceptTouchEvent() and all touch processing must happen in onTouchEvent() like normal.
·    For as long as you return false from this function, each following event (up to and including the final up) will be delivered first here and then to the target's onTouchEvent().
·    If you return true from here, you will not receive any following events: the target view will receive the same event but with the action  ACTION_CANCEL , and all further events will be delivered to your onTouchEvent() method and no longer appear here.
 
onInterceptTouchEvent()의 메커니즘 이 비교적 복잡 하기 때문에 위의 설명 도 비교적 복잡 하 다.정리 해 보면 기본 적 인 규칙 은:
1.         다운 이 벤트 는 우선 onIntercept TouchEvent()방법 으로 전 달 됩 니 다.
2.         이 ViewGroup 의 onInterceptTouchEvent()가 다운 이벤트 처리 가 끝 난 후에 return false 를 받 으 면 후속 move,up 등 사건 은 이 ViewGroup 에 먼저 전달 되 고 그 다음 에 다운 이벤트 와 같이 최종 목표 view 의 onTouchEvent()에 전 달 됩 니 다.
3.         이 ViewGroup 의 onInterceptTouchEvent()가 다운 이벤트 처리 가 끝 난 후에 return true 를 받 으 면 후속 move,up 등 사건 은 onInterceptTouchEvent()에 전달 되 지 않 고 다운 이벤트 와 마찬가지 로 이 ViewGroup 의 onTouchEvent()에 전 달 됩 니 다.대상 view 는 어떠한 사건 도 받 지 못 합 니 다.
4.         최종 적 으로 사건 을 처리 해 야 하 는 view 의 onTouchEvent()가 false 로 되 돌아 오 면 이 사건 은 이전 단계 의 view 의 onTouchEvent()로 전 달 됩 니 다.
5.         만약 최종 적 으로 사건 을 처리 해 야 하 는 view  의 onTouchEvent()가 true 로 돌 아 왔 습 니 다.그러면 후속 이 벤트 는 이 view 의 onTouchEvent()에 계속 전 달 될 수 있 습 니 다.
 
다음은 간단 한 실험 으로 상술 한 복잡 한 규칙 을 설명 한다.보 기 는 아래 에서 위로 모두 3 층 입 니 다.그 중에서 LayoutView 1 과 LayoutView 2 가 바로 LinearLayout 입 니 다.  MyTextView 는 TextView 입 니 다.
대응 하 는 xml 레이아웃 파일 은 다음 과 같 습 니 다.
 
 
다음은 구체 적 인 상황 을 살 펴 보 자.
1.         onInterceptTouchEvent()처리 down 사건 은 모두 false 로 돌아 가 고 onTouchEvent()처리 사건 은 모두 true 로 돌아 갑 니 다.
------------------------------------------------------------------------------------------------------------------------------
04-11 03:58:42.620: DEBUG/LayoutView1(614): onInterceptTouchEvent action:ACTION_DOWN
04-11 03:58:42.620: DEBUG/LayoutView2(614): onInterceptTouchEvent action:ACTION_DOWN
04-11 03:58:42.620: DEBUG/MyTextView(614): onTouchEvent action:ACTION_DOWN
04-11 03:58:42.800: DEBUG/LayoutView1(614): onInterceptTouchEvent action:ACTION_MOVE
04-11 03:58:42.800: DEBUG/LayoutView2(614): onInterceptTouchEvent action:ACTION_MOVE
04-11 03:58:42.800: DEBUG/MyTextView(614): onTouchEvent action:ACTION_MOVE
...//너무 많은 ACTION 생략MOVE
04-11 03:58:43.130: DEBUG/LayoutView1(614): onInterceptTouchEvent action:ACTION_UP
04-11 03:58:43.130: DEBUG/LayoutView2(614): onInterceptTouchEvent action:ACTION_UP
04-11 03:58:43.150: DEBUG/MyTextView(614): onTouchEvent action:ACTION_UP
------------------------------------------------------------------------------------------------------------------------------
이것 은 가장 흔히 볼 수 있 는 상황 이다.onInterceptTouchEvent 는 이벤트 전달 시 서 를 바 꾸 는 동작 을 하지 않 았 고 효과 적 으로 이 방법 을 덮어 쓰 지 않 은 것 과 같다.다양한 이벤트 의 전달 자 체 는 아래 에서 위로 향 하 는 것 을 볼 수 있 습 니 다.순 서 는 LayoutView 1->LayoutView 2->MyTextView 입 니 다.onInterceptTouchEvent 가 모두 false 로 돌아 갈 때 LayoutView 1 과 LayoutView 2 의 onTouchEvent 는 이 벤트 를 받 지 않 고 최종 적 으로 MyTextView 에 전 달 됩 니 다.
 
2.       LayoutView 1 의 onInterceptTouchEvent()처리 down 이벤트 가 true 로 돌아 갑 니 다.
MyTextView 의 onTouchEvent()처리 이 벤트 를 true 로 되 돌려 줍 니 다.
------------------------------------------------------------------------------------------------------------------------------
04-11 03:09:27.589: DEBUG/LayoutView1(446): onInterceptTouchEvent action:ACTION_DOWN
04-11 03:09:27.589: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_DOWN
04-11 03:09:27.629: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_MOVE
04-11 03:09:27.689: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_MOVE
...//너무 많은 ACTION 생략MOVE
04-11 03:09:27.959: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_UP
------------------------------------------------------------------------------------------------------------------------------
로그 에서 볼 수 있 듯 이 LayoutView 1 은 첫 번 째 다운 이 벤트 를 차단 할 때 return true 이기 때문에 후속 이벤트(첫 번 째 다운 포함)는 LayoutView 1 자체 가 처리 하고 이 벤트 는 전달 되 지 않 습 니 다.
 
3.         LayoutView 1,LayoutView 2 의 onInterceptTouchEvent()처리 down 이 벤트 를 false 로 되 돌려 줍 니 다.
MyTextView 의 onTouchEvent()처리 이 벤트 를 false 로 되 돌려 줍 니 다.
LayoutView 2 의 onTouchEvent()처리 이벤트 가 true 로 되 돌아 갑 니 다.
----------------------------------------------------------------------------------------------------------------------------
04-11 09:50:21.147: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_DOWN
04-11 09:50:21.147: DEBUG/LayoutView2(301): onInterceptTouchEvent action:ACTION_DOWN
04-11 09:50:21.147: DEBUG/MyTextView(301): onTouchEvent action:ACTION_DOWN
04-11 09:50:21.147: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_DOWN
04-11 09:50:21.176: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_MOVE
04-11 09:50:21.176: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_MOVE
04-11 09:50:21.206: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_MOVE
04-11 09:50:21.217: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_MOVE
...//너무 많은 ACTION 생략MOVE
04-11 09:50:21.486: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_UP
04-11 09:50:21.486: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_UP
----------------------------------------------------------------------------------------------------------------------------
이 를 통 해 알 수 있 듯 이 MyTextView 는 onTouchEvent()에서 return false,down 이 벤트 는 부모 view,즉 LayoutView 2 의 onTouchEvent()방법 으로 처리 되 었 으 며,LayoutView 2 의 onTouchEvent()에서 return true 로 전달 되 었 기 때문에 다운 이 벤트 는 LayoutView 1 에 업로드 되 지 않 았 습 니 다.후속 move 와 up 이 벤트 는 모두 LayoutView 2 의 onTouchEvent()에 전달 되 고 MyTextView 에 전달 되 지 않 았 음 을 주의 하 십시오.
 
----------------------------------------------------------------------------------------------------------------
여러분 의 요구 에 따라 저 는 소스 코드 를 붙 였 습 니 다.사실은 간단 합 니 다.바로 기초 파일 입 니 다.주로 사건 의 전달 을 관찰 하 는 데 사 용 됩 니 다.
 
주 활동:InterceptTouch Study Activity.java:
public   class  InterceptTouchStudyActivity  extends  Activity {

     static   final  String  TAG  =  "ITSActivity" ;

    TextView  tv ;

   

     /** Called when the activity is first created. */

     @Override

     public   void  onCreate(Bundle savedInstanceState) {

         super .onCreate(savedInstanceState);

        setContentView(R.layout. layers_touch_pass_test );

      }

 } 

 
 
      LayoutView1.java:
 
      public   class  LayoutView1  extends  LinearLayout {

       private   final  String  TAG  =  "LayoutView1" ;

          public  LayoutView1(Context context, AttributeSet attrs) {

          super (context, attrs);

         Log.d ( TAG , TAG );

     }

 

      @Override

      public   boolean  onInterceptTouchEvent(MotionEvent ev) {

          int  action = ev.getAction();

          switch (action){

          case  MotionEvent. ACTION_DOWN :

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

//            return true;

               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 ;

     }

 

      @Override

      protected   void  onLayout( boolean  changed,  int  l,  int  t,  int  r,  int  b) {

          //  TODO  Auto-generated method stub

          super .onLayout(changed, l, t, r, b);

     }

 

      @Override

      protected   void  onMeasure( int  widthMeasureSpec,  int  heightMeasureSpec) {

          //  TODO  Auto-generated method stub

          super .onMeasure (widthMeasureSpec, heightMeasureSpec);

     }

} 
 
LayoutView2.java:
 
 
public   class  LayoutView2  extends  LinearLayout {

     private   final  String  TAG  =  "LayoutView2" ;

   

     public  LayoutView2(Context context, AttributeSet attrs) {

        super (context, attrs);

       Log.d ( TAG , TAG );

    }

 

     @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 ;

    }  

} 
 
MyTextView.java:
 
 
public   class  MyTextView  extends  TextView {

     private   final  String  TAG  =  "MyTextView" ;

   

     public  MyTextView(Context context, AttributeSet attrs) {

        super (context, attrs);

       Log.d ( TAG , TAG );

    }

 

     @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   false ;

    }

   

     public   void  onClick(View v) {

       Log.d ( TAG ,  "onClick" );

    }

   

     public   boolean  onLongClick(View v) {

       Log.d ( TAG ,  "onLongClick" );

        return   false ;

    }

} 

좋은 웹페이지 즐겨찾기