programing

안드로이드:onIntercept의 차이Touch Event 및 dispatch Touch Event?

goodcopy 2022. 7. 2. 22:22
반응형

안드로이드:onIntercept의 차이Touch Event 및 dispatch Touch Event?

onInterceptTouchEvent ★★★★★★★★★★★★★★★★★」dispatchTouchEventAndroid 서??

Android 개발자 가이드에 따르면 터치 이벤트를 가로채기 위해 두 가지 방법을 모두 사용할 수 있습니다.MotionEvent)그런 떤떤떤 떤?? ????

하면 좋을까요?onInterceptTouchEvent,dispatchTouchEvent ★★★★★★★★★★★★★★★★★」onTouchEvent ViewGroup

이것을 명확하게 하기 위한 가장 좋은 장소는 소스 코드입니다.의사들은 이것을 설명하는데 비참할 정도로 불충분하다.

dispatch Touch Event는 Activity, View 및 View Group에서 실제로 정의되어 있습니다.터치 이벤트를 라우팅하는 방법을 결정하는 컨트롤러라고 생각하십시오.

예를 들어 View.dispatchTouchEvent는 터치 이벤트가 정의된 경우 OnTouchListener.onTouch 또는 TouchEvent 확장 메서드로 라우팅됩니다.

ViewGroup.dispatchTouchEvent의 경우 상황이 훨씬 복잡합니다.child.dispatchTouchEvent를 호출하여 어떤 하위 뷰가 이벤트를 받아야 하는지 파악해야 합니다.이는 기본적으로 터치 포인트 좌표를 포함하는 하위 뷰의 경계 직사각형을 파악하는 히트 테스트 알고리즘입니다.

그러나 이벤트를 적절한 하위 보기로 디스패치하기 전에 부모는 이벤트를 모두 감시하거나 가로챌 수 있습니다.이것이 onIntercept가Touch Event는 다음과 같습니다.따라서 히트 테스트를 수행하기 전에 먼저 이 메서드를 호출하고 이벤트가 납치된 경우(onIntercept에서 true를 반환함)TouchEvent)는 하위 뷰에 ACTION_CANCEL을 전송하여 터치 이벤트 처리(이전 터치 이벤트로부터)를 포기하도록 한 후 이후 상위 레벨의 모든 터치 이벤트가 onTouchListener.onTouch(정의된 경우) 또는 onTouchEvent()로 전송됩니다.이 경우에도 onIntercept는TouchEvent는 다시 호출되지 않습니다.

[Activity|]를 덮어쓰시겠습니까?View Group | View ] dispatch Touch Event?커스텀 루팅을 실행하고 있지 않는 한, 아마 실행하지 않는 것이 좋습니다.

주요 확장 메서드는 ViewGroup.onIntercept입니다.상위 수준에서 터치 이벤트를 스파이하거나 가로채려면 TouchEvent를, 메인 이벤트 처리에는 View.onTouchListener/View.onTouchEvent를 누르십시오.

전체적으로 너무 복잡한 디자인이지만 안드로이드 아피스는 단순함보다는 유연성에 더 기울어져 있습니다.

왜냐하면 이것은 구글에서의 첫 번째 결과이기 때문이다.Youtube에서 데이브 스미스의 멋진 이야기를 나누고 싶습니다. Android Touch 시스템 마스터링 및 슬라이드는 여기에서 확인할 수 있습니다.Android Touch System에 대해 깊이 이해할 수 있었습니다.

액티비티가 터치를 처리하는 방법:

  • Activity.dispatchTouchEvent()
    • 항상 제일 먼저 불림
    • 윈도우에 연결된 루트 뷰로 이벤트를 보냅니다.
    • onTouchEvent()
      • 이벤트를 소비하는 뷰가 없는 경우 호출됩니다.
      • 항상 마지막으로 호출됨

보기의 터치 처리 방법:

  • View.dispatchTouchEvent()
    • 존재하는 경우 먼저 청취자에게 이벤트를 보냅니다.
      • View.OnTouchListener.onTouch()
    • 사용하지 않을 경우 터치 자체를 처리합니다.
      • View.onTouchEvent()

View Group의 터치 처리 방법:

  • ViewGroup.dispatchTouchEvent()
    • onInterceptTouchEvent()
      • 하위 항목보다 우선해야 하는지 확인합니다.
      • ★★ACTION_CANCEL인 아이
      • true가되면 1' true'가 됩니다.ViewGroup의 모든 합니다.
    • 각 하위 보기에 대해(역순으로 추가됨)
      • 와 관련된 경우 '내부도' ('내부도')child.dispatchTouchEvent()
      • 이전 뷰에서 처리되지 않은 경우 다음 뷰로 디스패치합니다.
    • 이벤트를 처리하는 자녀가 없는 경우 청취자는 기회를 얻을 수 있습니다.
      • OnTouchListener.onTouch()
    • 리스너가 없거나 리스너가 처리되지 않은 경우
      • onTouchEvent()
  • 인터셉트된 이벤트가 하위 단계를 뛰어넘습니다.

또, 커스텀 터치 코드의 예도 github.com/devunwired/ 에 게재하고 있습니다.

답변: 기본적으로dispatchTouchEvent() is is ViewView현재 진행 중인 제스처에 관심이 있습니다.①의 ViewGroupViewGroup 수 능력이 있다dispatchTouchEvent()- ,, 에 - ,, 호, 호, -, -, -, -, -, -, -, -, -.dispatchTouchEvent()★★★★★★★★★★★★★★★★★★★★★★★.ViewGroupViewGroup onInterceptTouchEvent()-true는 true를 반환합니다.다른 점은 말이다.dispatchTouchEvent()를 하고 있습니다.MotionEvents ★★★★★★★★★★★★★★★★★」onInterceptTouchEvent는 대행 수신(자녀에게 디스패치하지 않음) 또는 수신(자녀에게 디스패치하지 않음) 여부를 나타냅니다.

View Group의 코드는 대략 다음과 같습니다(매우 단순화).

public boolean dispatchTouchEvent(MotionEvent ev) {
    if(!onInterceptTouchEvent()){
        for(View child : children){
            if(child.dispatchTouchEvent(ev))
                return true;
        }
    }
    return super.dispatchTouchEvent(ev);
}

보충 답변

다음은 다른 답변에 대한 시각적 보충 자료입니다.제 모든 답은 여기 있습니다.

여기에 이미지 설명 입력

여기에 이미지 설명 입력

dispatchTouchEvent()의 of의 ViewGrouponInterceptTouchEvent() 이벤트 함께)를 즉시 해야 하는지 를 선택하다onTouchEvent() 에 알립니다.dispatchTouchEvent()그 아이들의 방법.

이 방법들은 많은 혼란이 있지만, 사실 그렇게 복잡하지는 않다.대부분의 혼란은 다음과 같습니다.

  1. 의 '' ''가View/ViewGroup 그 중 된 것을 .onTouchEvent,dispatchTouchEvent ★★★★★★★★★★★★★★★★★」onInterceptTouchEvent에 대해서만 요구됩니다.MotionEvent.ACTION_DOWN 없이의 진실 없이onTouchEvent모션 이벤트
  2. 에서 항목 중하는 것이 TouchEvent, onIntercept "ViewGroup" "TouchEvent 전용으로 호출됩니다"MotionEvent.ACTION_DOWN에도 true가 반환됩니다onTouchEvent.

처리순서는 다음과 같습니다.

  1. dispatchTouchEvent출됩니니다다
  2. onInterceptTouchEvent 필요로 하다MotionEvent.ACTION_DOWN 중 가 "View Group"에서 했을 때onTouchEvent.
  3. onTouchEvent는 처음에 되며, 하지 않으면 "View Group", "True", "True", "True"로 됩니다.View/ViewGroup.

미리보기를 TouchEvents/MotionEvents자녀 이벤트를 비활성화하지 않고 다음 두 가지 작업을 수행해야 합니다.

  1. 「」를 .dispatchTouchEvent를 하고 super.dispatchTouchEvent(ev);
  2. 「」를 .onTouchEvent "true" 또는 "true"를 수 MotionEventMotionEvent.ACTION_DOWN.

스와이프 이벤트와 같은 제스처를 검출하려면 , 제스처를 검출하지 않는 한, 자녀의 다른 이벤트를 무효로 하지 않고, 다음과 같이 할 수 있습니다.

  1. 위에서 설명한 대로 MotionEvents를 미리 보고 제스처를 감지하면 플래그를 설정합니다.
  2. onInterceptTouchEvent플래그가 자녀의 모션 이벤트 처리를 취소하도록 설정되어 있는 경우. 플래그를 때도 합니다.onIntercept는 onIntercept로 리셋하기 입니다. TouchEvent가 될 되지 않습니다.MotionEvent.ACTION_DOWN.

FrameLayoutAndroid를 때문에 C이만, ('Xamarin Android'는 C#입니다).

public override bool DispatchTouchEvent(MotionEvent e)
{
    // Preview the touch event to detect a swipe:
    switch (e.ActionMasked)
    {
        case MotionEventActions.Down:
            _processingSwipe = false;
            _touchStartPosition = e.RawX;
            break;
        case MotionEventActions.Move:
            if (!_processingSwipe)
            {
                float move = e.RawX - _touchStartPosition;
                if (move >= _swipeSize)
                {
                    _processingSwipe = true;
                    _cancelChildren = true;
                    ProcessSwipe();
                }
            }
            break;
    }
    return base.DispatchTouchEvent(e);
}

public override bool OnTouchEvent(MotionEvent e)
{
    // To make sure to receive touch events, tell parent we are handling them:
    return true;
}

public override bool OnInterceptTouchEvent(MotionEvent e)
{
    // Cancel all children when processing a swipe:
    if (_cancelChildren)
    {
        // Reset cancel flag here, as OnInterceptTouchEvent won't be called until the next MotionEventActions.Down:
        _cancelChildren = false;
        return true;
    }
    return false;
}

다음 중 하나: dispatchTouchEvent()제일 먼저 부르겠습니다.

간단한 조언: 덮어쓰지 말 것dispatchTouchEvent()컨트롤이 어렵기 때문에 퍼포먼스가 저하될 수 있습니다.,을 제안합니다.onInterceptTouchEvent().


에서는 액티비티 그룹 매우 에, 이러한 는, 「」의 「」/「」/「」/「」의 「」에서 코드에 대한 합니다.ViewGroup (비밀(이행)dispatchTouchEvent()

onInterceptTouchEvent() 먼저 호출하고 ACTION 이벤트를 각각 아래로 이동 -> 위로 호출합니다.두 가지 경우가 있습니다.

  1. 3가지 경우(ACTION_DOWN, ACTION_MOVE, ACTION_UP)에서 false를 반환할 경우 부모에게는 이 터치 이벤트가 필요하지 않으므로 부모에게는 전화하지 않지만 자녀에게는 전화하지 않습니다.단, 주의하시기 바랍니다.

    • onInterceptTouchEvent() 가 전화를 하지 한requestDisallowInterceptTouchEvent(true)
    • 터치한 발생 ), 를 FalseDOWN으로 되돌립니다.onTouch()부모에 대해서요
  2. 반대로 true를 반환하면 부모는 즉시터치이벤트를 도용합니다.onInterceptTouchEvent()부모 대신 부모가 호출되고 모든 자녀가 마지막 액션 이벤트인 ACTION_CANCEL을 받게 됩니다(따라서 부모가 터치 이벤트를 훔쳤다는 의미이며, 이후 자녀는 터치 이벤트를 처리할 수 없습니다).의 흐름onInterceptTouchEvent()와 약간의return false를 return true로 .

    • ACTION_DOWN에서 한다.onTouch()ACTION_DOWN을 다시 수신하고 다음 액션(ACTION_MOVE, ACTION_UP)을 수신합니다.
    • ACTION_MOVE에서 한다.onTouch()다음 ACTION_MOVE를 수신합니다(같은 ACTION_MOVE가 아님).onInterceptTouchEvent()) 및 다음 액션ACTION_MOVE, ACTION_UP).
    • ACTION_UP에서 한다.onTouch()부모들이 터치를 훔치기엔 너무 늦었기 때문에 전혀 전화하지 않을 이다.

하나 더 중요한 은 의 이벤트의 ACTION_DOWN 입니다.onTouch()뷰가 해당 이벤트로부터 더 많은 액션을 받을지 여부를 결정합니다.가 'ACTION_DOWN'의 '에서 onTouch()이는 뷰가 해당 이벤트에서 더 많은 액션을 받을 의사가 있음을 의미합니다. 않으면 ACTION_DOWN의 합니다.onTouch()뷰가 해당 이벤트로부터 더 이상 액션을 수신하지 않음을 나타냅니다.

저는 이 웹페이지 http://doandroids.com/blogs/tag/codeexample/에서 매우 직관적인 설명을 듣게 되었습니다.여기서부터:

  • boolean onTouchEvent(MotionEvent ev) - 이 보기를 대상으로 하는 터치 이벤트가 탐지될 때마다 호출됩니다.
  • boolean onInterceptTouchEvent(MotionEvent ev) - 이 ViewGroup 또는 해당 하위 ViewGroup을 대상으로 하는 터치 이벤트가 탐지될 때마다 호출됩니다.이 함수가 true를 반환하면 MotionEvent가 대행 수신됩니다. 즉, 하위 함수가 아니라 이 View의 onTouchEvent로 전달됩니다.

dispatchTouchEvent 처리 전 onIntercept터치 이벤트

다음의 간단한 예를 사용합니다.

   main = new LinearLayout(this){
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            System.out.println("Event - onInterceptTouchEvent");
            return super.onInterceptTouchEvent(ev);
            //return false; //event get propagated
        }
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            System.out.println("Event - dispatchTouchEvent");
            return super.dispatchTouchEvent(ev);
            //return false; //event DONT get propagated
        }
    };

    main.setBackgroundColor(Color.GRAY);
    main.setLayoutParams(new LinearLayout.LayoutParams(320,480));    


    viewA = new EditText(this);
    viewA.setBackgroundColor(Color.YELLOW);
    viewA.setTextColor(Color.BLACK);
    viewA.setTextSize(16);
    viewA.setLayoutParams(new LinearLayout.LayoutParams(320,80));
    main.addView(viewA);

    setContentView(main);

로그는 다음과 같습니다.

I/System.out(25900): Event - dispatchTouchEvent
I/System.out(25900): Event - onInterceptTouchEvent

이러한 2개의 핸들러를 사용하고 있는 경우는, 우선 dispatch Touch Event 를 사용해 이벤트를 처리해, on Intercept 로 이동합니다.터치 이벤트

또 다른 차이점은 dispatchTouchEvent가 'false'를 반환하는 경우 이벤트가 하위(이 경우 EditText)로 전파되지 않는 반면 onIntercept에서는 false를 반환하는 경우)입니다.TouchEvent 이벤트가 EditText로 디스패치됩니다.

ViewGroup 하위 클래스 내의 다음 코드는 상위 컨테이너가 터치 이벤트를 수신하지 못하도록 합니다.

  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    // Normal event dispatch to this container's children, ignore the return value
    super.dispatchTouchEvent(ev);

    // Always consume the event so it is not dispatched further up the chain
    return true;
  }

배경 뷰가 터치 이벤트에 반응하지 않도록 커스텀 오버레이와 함께 사용했습니다.

정답은 이 비디오 https://www.youtube.com/watch?v=SYoN-OvdZ3M&list=PLonJJ3BVjZW6CtAMbJz1XD8ELUs1KXaTD&index=19과 다음 3개의 비디오에서 찾을 수 있습니다.모든 터치 이벤트가 매우 잘 설명되고 매우 명확하며 예시로 가득합니다.

주요 차이점은 다음과 같습니다.

• Activity.dispatch Touch Event (Motion Event) - 이 • 、 • • • • • • • • • 。
•ViewGroup.onInterceptTouchEvent(MotionEvent) - ViewGroup 。

의 ★★★★★onInterceptTouchEvent()항상 의 시작점입니다.ACTION_DOWN이치노

제스처를 Group에서 하십시오.onInterceptTouchEvent(). true가 반환됩니다.onTouchEvent() 번까지 후속 합니다.ACTION_UP ★★★★★★★★★★★★★★★★★」ACTION_CANCEL 사이의 는 " " " " " 입니다.ACTION_DOWN ★★★★★★★★★★★★★★★★★」ACTION_UP ★★★★★★★★★★★★★★★★★」ACTION_CANCELACTION_MOVE일반적으로 스크롤/수직 제스처로 인식됩니다.

false에서 onInterceptTouchEvent()의 , 「 」onTouchEvent()'진짜'에서 '진짜'로 까지 '진짜'됩니다.onInterceptTouchEvent().

출처 : http://neevek.net/posts/2013/10/13/implementing-onInterceptTouchEvent-and-onTouchEvent-for-ViewGroup.html

public boolean dispatchTouchEvent(MotionEvent ev){
    boolean consume =false;
    if(onInterceptTouchEvent(ev){
        consume = onTouchEvent(ev);
    }else{
        consume = child.dispatchTouchEvent(ev);
    }
}

Activity와 View에는 모두 dispatchTouchEvent() 메서드와 onTouchEvent 메서드가 있습니다.View Group에도 이 메서드가 있지만 onIntercept라는 다른 메서드가 있습니다.터치 이벤트이러한 메서드의 반환 유형은 부울형이며 반환값을 사용하여 디스패치루트를 제어할 수 있습니다.

Android의 이벤트 디스패치는 [액티비티]-> [ View Group ]-> [ View ]에서 시작합니다.

간단한 답변:

가로채기TouchEvent가 setOn보다 우선함Touch Listener.

언급URL : https://stackoverflow.com/questions/9586032/android-difference-between-onintercepttouchevent-and-dispatchtouchevent

반응형