2017-05-12 10 views
1

그래서 나는 다음 뷰 구조 한 :안드로이드 : 아이 뷰에 부모로부터 처리 인터셉트 터치 제스처

  • 있는 LinearLayout은
    • HorizontalScrollView
    • 다른 아이는

부모 LinearLayout에는 클릭 할 수있는 사용자 정의 선택기가 있습니다 (c 눌렀을 때 색상이 매달려 있음). LinearLayout 내에서 HorizontalScrollView를 터치하고 스크롤 모션이 아닌 한 LinearLayout에서 터치를 처리 할 수 ​​있기를 원합니다. 스크롤 모션을 수행하면 HorizontalScrollView가 제스처를 가로 채고 LinearLayout의 터치를 취소해야합니다. 기본적으로 나는 표준 인 부모와는 반대로 어린이보기에서 제스처를 가로 챌 수 있기를 원합니다.

나는 다음과 같이 확장 클래스를 작성하여 수동으로 MotionEvent를 처리하기 위해 노력했다 : 이것은 거의 일

public override bool OnInterceptTouchEvent(MotionEvent ev) 
{ 
    // Handle the motion event even if a child returned true for OnTouchEvent 
    base.OnTouchEvent(ev); 
    return base.OnInterceptTouchEvent(ev); 
} 

HorizontalScrollView

public override bool OnTouchEvent(MotionEvent e) 
{ 
    if (e.Action == MotionEventActions.Down) 
    { 
     _intialXPos = e.GetX(); 
    } 

    if (e.Action == MotionEventActions.Move) 
    { 
     float xDifference = Math.Abs(e.GetX() - _intialXPos); 
     if (xDifference > _touchSlop) 
     { 
      // Prevent the parent OnInterceptTouchEvent from being called, thus it will no longer be able to handle motion events for this gesture 
      Parent.RequestDisallowInterceptTouchEvent(true); 
     } 
    } 

    return base.OnTouchEvent(e); 
} 

있는 LinearLayout합니다. HorizontalScrollView를 터치하면 LinearLayout은 눌려진 상태 UI를 표시하고 클릭이 완료되면 활성화됩니다. HorizontalScrollView를 터치하고 스크롤하면 스크롤이 작동합니다. 스크롤을 놓을 때 LinearLayout의 클릭 핸들러는 가로 채기 때문에 실행되지 않습니다. 그러나 문제는 LinearLayout이 눌린 상태로 스크롤하기 시작하기 전에 제스처가 완료된 후에도 리셋되지 않는다는 것입니다. LinearLayout의 제스처를 수동으로 취소하려고 시도한 또 다른 시도에서 다른 문제가 계속 발생했습니다. 또한 LinearyLayout에는 그 안에 다른 버튼이있어서 클릭하면 부모 LinearLayout이 눌려진 상태를 표시하지 않아야합니다. 어떤 제안? 자녀의 터치 이벤트를 가로 채기위한 설정 패턴이 있습니까? 두 클래스가 서로에 대해 알고 있다면 가능할 것이라고 확신하지만,이를 연결하는 것을 피하려고합니다.

답변

0

모든 경우에 나를 위해 다음 작업 :

InterceptableLinearLayout

public override bool DispatchTouchEvent(MotionEvent e) 
{ 
    bool dispatched = base.DispatchTouchEvent(e); 
    // Handle the motion event even if a child returns true in OnTouchEvent 
    // The MotionEvent may have been canceled by the child view 
    base.OnTouchEvent(e); 

    return dispatched; 
} 

public override bool OnTouchEvent(MotionEvent e) 
{ 
    // We are calling OnTouchEvent manually, if OnTouchEvent propagates back to this layout do nothing as it was already handled. 
    return true; 
} 

InterceptCapableChildView

public override bool OnTouchEvent(MotionEvent e) 
{ 
    bool handledTouch = base.OnTouchEvent(e); 

    if ([Meets Condition to Intercept Gesture]) 
    { 
     // If we are inside an interceptable viewgroup, intercept the motionevent by sending the cancel action to the parent 
     e.Action = MotionEventActions.Cancel; 
    } 

    return handledTouch; 
}