2017-05-12 1 views
1

So habe ich die folgende Ansicht Struktur:Android: Intercept Berührgeste vom Elternteil auf den Kinder Umgang

  • Linearlayout
    • HorizontalScrollView
    • Andere Kinderansichten

Das übergeordnete LinearLayout verfügt über einen anpassbaren Selektor (c ändert die Farbe beim Drücken). Ich möchte in der Lage sein, die HorizontalScrollView innerhalb des LinearLayout zu berühren und die Berührung in der LinearLayout noch zu behandeln, solange es keine Scroll-Bewegung ist. Wenn ich eine Scroll-Bewegung mache, sollte die HorizontalScrollView die Geste abfangen und die Berührung für das LinearLayout abbrechen. Grundsätzlich möchte ich in der Lage sein, die Geste von einer Kindansicht abzufangen, im Gegensatz zu dem Elternteil, der der Standard ist.

Ich habe versucht, indem Erweiterungsklassen die Motion manuell zu handhaben, die folgendes tun:

Linearlayout

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); 
} 

Diese fast gearbeitet. Wenn ich HorizontalScrollView berühre, zeigt das LinearLayout die Benutzeroberfläche des gedrückten Status an und wird aktiviert, wenn der Klick abgeschlossen ist. Wenn ich den HorizontalScrollView berühre und scrolle, funktioniert das Scrollen. Wenn ich den Bildlauf loslasse, wird der Click-Handler für das LinearLayout nicht ausgelöst, weil es abgefangen wurde. Aber das Problem ist, dass bevor ich mit dem Scrollen anfange, das LinearLayout in den gedrückten Zustand wechselt und es nicht zurückgesetzt wird, selbst nachdem die Geste beendet ist. In meinem zusätzlichen Versuch, die Geste für das LinearLayout manuell abzubrechen, lief ich in anderen Problemen weiter. Darüber hinaus verfügt das LinearyLayout über weitere Schaltflächen, die es dem übergeordneten LinearLayout beim Klicken nicht ermöglichen, den gedrückten Zustand anzuzeigen. Irgendwelche Vorschläge? Gibt es ein festgelegtes Muster zum Abfangen von Berührungsereignissen von einem Kind? Ich bin mir sicher, dass es möglich ist, wenn beide Klassen voneinander wissen, aber ich versuche, sie zu vermeiden.

Antwort

0

Die folgende Arbeit für mich für alle Fälle:

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; 
} 
Verwandte Themen