30 분 동안 안 드 로 이 드 터치 이벤트 배포 메커니즘 파악

Touch 사건 배포 에는 두 명의 주인공 만 있다.View Group 과 View.Activity 의 Touch 사건 은 사실상 내부 의 ViewGroup 의 Touch 사건 을 호출 하여 ViewGroup 으로 직접 처리 할 수 있 습 니 다.
View 는 ViewGroup 내 에서 도 다른 ViewGroup 내 에서 도 내부 의 ViewGroup 을 View 로 분석 할 수 있다.
ViewGroup 의 관련 사건 은 세 가지 가 있 는데 그것 이 바로 onInterceptTouchEvent,dispatchTouchEvent,onTouchEvent 이다.View 의 관련 사건 은 두 가지 만 있 습 니 다.dispatchTouchEvent,onTouchEvent 입 니 다.
먼저 ViewGroup 의 처리 절 차 를 분석 합 니 다.먼저 구조 모델 개념 이 있어 야 합 니 다.ViewGroup 과 View 는 나무 구 조 를 구성 하고 맨 윗 층 은 Activity 의 ViewGroup 입 니 다.아래 에 몇 개의 ViewGroup 노드 가 있 고 각 노드 아래 에 몇 개의 ViewGroup 노드 나 View 노드 가 있 으 며 순서대로 유추 합 니 다.그림:

터치 이벤트(터치 이벤트 의 경우)가 루트 노드,즉 Acitivty 의 ViewGroup 에 도 착 했 을 때 순서대로 내 려 갑 니 다.내 려 오 는 과정 은 하위 View(ViewGroup)의 dispatchTouchEvent 방법 으로 이 루어 집 니 다.쉽게 말 하면 ViewGroup 이 포함 하고 있 는 하위 View 를 옮 겨 다 니 며 각 View 의 dispatchTouchEvent 방법 을 호출 하고,하위 View 가 ViewGroup 일 때 는 ViwGroup 의 dispatchTouchEvent 방법 을 호출 하여 내부 View 의 dispatchTouchEvent 방법 을 계속 호출 합 니 다.위의 예 에서 보 낸 메시지 의 순 서 는 다음 과 같다.①-②-⑤-⑥-⑦-③-④.dispatchTouchEvent 방법 은 이벤트 의 배포 만 담당 합 니 다.boolean 형식의 반환 값 을 가지 고 있 습 니 다.true 로 돌아 갈 때 순서대로 보 내 는 것 이 중 단 됩 니 다.위의 예 에서 ⑤ 의 dispatchTouchEvent 가 true 로 되 돌아 오 면 ⑥-⑦-③-④ 는 이번 Touch 사건 을 받 지 못 한다.간단 한 코드 로 이해 하기:
 

/**
   * ViewGroup
   * @param ev
   * @return
   */
  public boolean dispatchTouchEvent(MotionEvent ev){
    ....//    ,    
    View[] views=getChildView();
    for(int i=0;i<views.length;i++){
      //   Touch         View   
      if(...){
      if(views[i].dispatchTouchEvent(ev))
       return true;
       }
    }
    ...//    ,    
  }
  /**
   * View
   * @param ev
   * @return
   */
  public boolean dispatchTouchEvent(MotionEvent ev){
    ....//    ,    
    return false;
  }
이 를 통 해 알 수 있 듯 이 View Group 의 dispatchTouchEvent 는 진정 으로'배포'작업 을 수행 하고 있 으 며,View 의 dispatchTouchEvent 방법 은 배포 작업 을 수행 하지 않 거나 배포 대상 은 자신 이 며,touch 사건 을 자신 에 게 맡 길 지 여 부 를 결정 하 는 방법 은 바로 onTouchEvent 사건 이다.사실 서브 뷰 의 dispatchTouchEvent 방법 이 실제로 실 행 된 코드 는 이 렇 습 니 다.

/**
   * View
   * @param ev
   * @return
   */
  public boolean dispatchTouchEvent(MotionEvent ev){
    ....//    ,    
    return onTouchEvent(event);
  }
일반적인 상황 에서 우 리 는 배포 논 리 를 실행 하지 않 기 때문에 일반 View 에서 dispatchTouchEvent 방법 을 다시 써 서 는 안 된다.Touch 이벤트 가 View 에 도 착 했 을 때 우리 가 해 야 할 일 은 onTouch 이벤트 에서 처리 하 는 지 여부 입 니 다.
그렇다면 View Group 의 onTouchEvent 사건 은 언제 처 리 됐 을 까?ViewGroup 의 모든 하위 View 가 false 로 돌아 갈 때 onTouchEvent 이 벤트 는 실 행 됩 니 다.ViewGroup 은 View 에 계승 되 었 기 때문에 View 의 dispatchTouchEvent 방법 을 호출 하여 onTouchEvent 이 벤트 를 수행 합 니 다.
 
현재 로 서 는 모든 onTouch Event 를 false 로 되 돌려 주면 모든 하위 컨트롤 이 이번 Touch 이벤트 에 응답 할 수 있 을 것 같 습 니 다.그러나 반드시 설명해 야 할 것 은 이곳 의 터치 사건 은 Acition 에 국한 된다 는 것 이다.다운 이벤트,즉 사건 을 터치 하고,AcitonUP 와 ActionMOVE 는 실행 하지 않 는 다.사실 하나의 완전한 Touch 사건 은 하나의 Down,하나의 Up 과 여러 개의 Move 로 구성 되 어야 합 니 다.Down 방식 은 dispatchTouchEvent 를 통 해 배포 되 며 전체 Touch 요청 을 처리 해 야 하 는 View 를 찾기 위해 배포 된다.어떤 View 나 View Group 의 onTouch Event 사건 이 true 로 돌 아 왔 을 때 이번 요청 을 진정 으로 처리 해 야 하 는 View,그 후의 Aciton 임 을 나타 낸다.UP 와 ActionMOVE 는 그것 이 처리 할 것 이다.모든 하위 View 의 onTouch Event 가 false 로 돌아 갈 때 이번 Touch 요청 은 루트 View Group,즉 Activity 가 직접 처리 합 니 다.
개 선 된 View Group 의 dispatch TouchEvent 방법 을 살 펴 보 세 요.

View mTarget=null;//    Touch     View
  public boolean dispatchTouchEvent(MotionEvent ev) {

    //....    ,    
    
    if(ev.getAction()==KeyEvent.ACTION_DOWN){
      //  Down  ,   Null

      if(!onInterceptTouchEvent()){
      mTarget=null;
      View[] views=getChildView();
      for(int i=0;i<views.length;i++){
        if(views[i].dispatchTouchEvent(ev))
          mTarget=views[i];
          return true;
      }
     }
    }
    //  View    down   ,ViewGroup    。     Touch    Down、Up Move
    if(mTarget==null){
      return super.dispatchTouchEvent(ev);
    }
    //...    ,    
    if(onInterceptTouchEvent()){
     //...    ,      
     }
//    Action_Down        ,  Move UP     。
    return mTarget.dispatchTouchEvent(ev);

  }

View Group 에 onIntercept TouchEvent 가 있 는데 이름 을 보면 차단 사건 임 을 알 수 있 습 니 다.이 차단 사건 은 두 가지 상황 으로 나 누 어 설명 해 야 한다.
1.만약 에 우리 가 특정한 View Group 의 onInterceptTouch Event 에서 Action 을 Down 으로 하 는 Touch 사건 을 true 로 되 돌려 준다 면 이 View Group 의 모든 하 발 작업 을 차단 하 는 것 을 나타 낸다.이런 상황 에서 mTarget 은 계속 null 이 될 것 이다.mTarget 은 Down 이벤트 에서 값 을 부여 하기 때문이다.mTarge 가 null 이기 때문에 이 View Group 의 onTouchEvent 이벤트 가 실 행 됩 니 다.이 경우 이 뷰 그룹 을 직접 뷰 로 취급 할 수 있다.
2.만약 에 우리 가 특정한 View Group 의 onInterceptTouch Event 에서 Acion 을 Down 으로 하 는 Touch 사건 을 모두 false 로 돌아 가 고 다른 것 은 모두 True 로 돌아 가 는 상황 에서 Down 사건 은 정상적으로 나 눌 수 있 습 니 다.만약 에 하위 View 가 모두 false 로 돌아 가면 mTarget 은 비어 있 고 영향 이 없습니다.어떤 키 View 가 true 로 돌아 가면 mTarget 이 할당 되 었 습 니 다.ActionMove 와 AcitonUP 가 이 View Group 에 배포 되면 mTarget 에 Action 을 나 눠 줍 니 다.Delete 의 MotionEvent 와 함께 mTarget 의 값 을 비 워 다음 ActionMove(이전 작업 이 UP 가 아니라면)는 View Group 의 onTouch Event 로 처 리 됩 니 다.
상황 이 비교적 많이 사용 되 었 고 상황 두 사람 은 아직 사용 장면 을 찾 지 못 했다.
처음부터 끝까지 정리 하 다.
1.Touch 사건 배포 에는 두 명의 주인공 만 있다.View Group 과 View.ViewGroup 은 onInterceptTouchEvent,dispatchTouchEvent,onTouchEvent 세 가지 관련 사건 을 포함한다.View 는 dispatchTouchEvent,onTouchEvent 두 가지 관련 사건 을 포함한다.그 중에서 도 뷰 그룹 은 뷰 에 이 어 받 았 다.
2.ViewGroup 과 View 는 트 리 구 조 를 구성 하고 뿌리 노드 는 Activity 내부 에 포 함 된 ViwGroup 이다.
3.터치 이 벤트 는 ActionDown、Action_Move、Aciton_UP 로 구성 되 어 있 으 며,그 중 한 번 의 완전한 터치 이벤트 중 다운 과 업 은 하나 뿐 이 며,Move 는 몇 개 로 0 개 로 구성 되 어 있다.
4.Acitivty 가 Touch 이 벤트 를 받 았 을 때 하위 View 를 옮 겨 다 니 며 Down 이 벤트 를 배포 합 니 다.View Group 의 옮 겨 다 니 는 것 은 재 귀적 인 것 으로 볼 수 있다.배포 의 목적 은 이번 전체 터치 사건 을 진정 으로 처리 해 야 할 View 를 찾기 위해 서 입 니 다.이 View 는 onTouchu Event 결과 에서 true 로 돌아 갑 니 다.
5.어떤 키 뷰 가 true 로 돌아 갈 때 다운 이벤트 의 배 포 를 중단 하고 뷰 그룹 에 이 하위 뷰 를 기록 합 니 다.이 어 진 Move 와 Up 이 벤트 는 이 하위 뷰 에서 직접 처리 합 니 다.하위 View 는 ViewGroup 에 저 장 된 다 층 ViewGroup 의 노드 구조 이기 때문에 상급 ViewGroup 은 사건 을 실제 처리 하 는 View 가 있 는 ViewGroup 대상 을 저장 합 니 다.예 를 들 어 ViewGroup 0-ViewGroup 1-TextView 의 구조 에서 TextView 는 true 로 되 돌아 가 ViewGroup 1 에 저 장 됩 니 다.ViewGroup 1 도 true 로 되 돌아 가 ViewGroup 0 에 저 장 됩 니 다.Move 와 UP 이벤트 가 올 때 ViewGroup 0 에서 ViewGroup 1 로 전달 되 고 ViewGroup 1 에서 TextView 로 전 달 됩 니 다.
6.ViewGroup 의 모든 하위 View 가 Down 이 벤트 를 캡 처 하지 않 을 때 ViewGroup 자체 의 onTouch 이 벤트 를 촉발 합 니 다.트리거 방식 은 슈퍼.dispatchTouchEvent 함수,즉 부모 클래스 View 의 dispatchTouchEvent 방법 을 호출 하 는 것 입 니 다.모든 하위 뷰 가 처리 되 지 않 은 상태 에서 Acitivity 를 촉발 하 는 onTouchEvent 방법.
7.onInterceptTouchEvent 는 두 가지 역할 을 합 니 다.1.Down 사건 의 배 포 를 차단 합 니 다.2.Up 과 Move 이 벤트 를 대상 View 에 전달 하 는 것 을 중단 하고 대상 View 가 있 는 ViewGroup 이 Up 과 Move 이 벤트 를 캡 처 합 니 다.
 보충:
"터치 사건 은 ActionDown、Action_Move、Aciton_UP 로 구성 되 어 있 으 며,그 중 한 번 의 완전한 터치 이벤트 중 다운 과 업 은 하나 뿐 이 며,Move 는 몇 개 로 0 개 로 구성 되 어 있 습 니 다."여기 서 덧 붙 여 보면 사실 UP 사건 은 0 개 일 수 있 습 니 다.
이상 은 본 고의 모든 내용 이 므 로 Touch 사건 의 배포 체 제 를 이해 하 는 데 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기