Android
Wybierz Wydarzenia
Szukaj…
Jak zmieniać zdarzenia dotyku w grupie dzieci i rodziców
-
onTouchEvents()
dla zagnieżdżonych grup widoków może być zarządzany przez wartośćboolean
onInterceptTouchEvent .
Wartość domyślna dla OnInterceptTouchEvent
to false.
onTouchEvent
rodzica jest odbierany przed dzieckiem. Jeśli OnInterceptTouchEvent
zwraca false, wysyła zdarzenie motion w dół łańcucha do procedury obsługi OnTouchEvent
dziecka. Jeśli zwróci wartość true, rodzic zajmie się zdarzeniem dotykowym.
Mogą jednak wystąpić sytuacje, w których chcemy, aby niektóre elementy potomne zarządzały OnTouchEvent
a niektóre były zarządzane przez widok nadrzędny (lub ewentualnie nadrzędny element nadrzędny).
Można to zarządzać na więcej niż jeden sposób.
- Jednym ze sposobów ochrony elementu potomnego przed
OnInterceptTouchEvent
rodzica jest implementacja requestDisallowInterceptTouchEvent .
public void requestDisallowInterceptTouchEvent (boolean disallowIntercept)
Zapobiega to zarządzaniu OnTouchEvent
przez ten widok nadrzędny dla tego elementu, jeśli element ma włączone procedury obsługi zdarzeń.
Jeśli wartość OnInterceptTouchEvent
ma wartość false, wartość OnTouchEvent
elementu OnTouchEvent
zostanie oceniona. Jeśli masz metody w elementach potomnych obsługujących różne zdarzenia dotykowe, wszelkie powiązane funkcje obsługi zdarzeń, które zostaną wyłączone, zwrócą OnTouchEvent do elementu nadrzędnego.
Ta odpowiedź:
Wizualizacja tego, jak przebiega propagacja zdarzeń dotykowych:
parent -> child|parent -> child|parent -> child views.
- Innym sposobem jest zwracanie różnych wartości z
OnInterceptTouchEvent
dla elementu nadrzędnego.
Ten przykład pochodzi z zarządzania zdarzeniami dotykowymi w grupie ViewGroup i pokazuje, jak przechwycić OnTouchEvent
dziecka, gdy użytkownik przewija.
4a.
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
/*
* This method JUST determines whether we want to intercept the motion.
* If we return true, onTouchEvent will be called and we do the actual
* scrolling there.
*/
final int action = MotionEventCompat.getActionMasked(ev);
// Always handle the case of the touch gesture being complete.
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
// Release the scroll.
mIsScrolling = false;
return false; // Do not intercept touch event, let the child handle it
}
switch (action) {
case MotionEvent.ACTION_MOVE: {
if (mIsScrolling) {
// We're currently scrolling, so yes, intercept the
// touch event!
return true;
}
// If the user has dragged her finger horizontally more than
// the touch slop, start the scroll
// left as an exercise for the reader
final int xDiff = calculateDistanceX(ev);
// Touch slop should be calculated using ViewConfiguration
// constants.
if (xDiff > mTouchSlop) {
// Start scrolling!
mIsScrolling = true;
return true;
}
break;
}
...
}
// In general, we don't want to intercept touch events. They should be
// handled by the child view.
return false;
}
To jest kod z tego samego linku pokazujący, jak utworzyć parametry prostokąta wokół twojego elementu:
4b.
// The hit rectangle for the ImageButton
myButton.getHitRect(delegateArea);
// Extend the touch area of the ImageButton beyond its bounds
// on the right and bottom.
delegateArea.right += 100;
delegateArea.bottom += 100;
// Instantiate a TouchDelegate.
// "delegateArea" is the bounds in local coordinates of
// the containing view to be mapped to the delegate view.
// "myButton" is the child view that should receive motion
// events.
TouchDelegate touchDelegate = new TouchDelegate(delegateArea, myButton);
// Sets the TouchDelegate on the parent view, such that touches
// within the touch delegate bounds are routed to the child.
if (View.class.isInstance(myButton.getParent())) {
((View) myButton.getParent()).setTouchDelegate(touchDelegate);
}