Android
Коснитесь событий
Поиск…
Как варьироваться между дочерними и родительскими группами событий касания
-
onTouchEvents()
для вложенных групп представлений может управлятьсяboolean
onInterceptTouchEvent .
Значение по умолчанию для OnInterceptTouchEvent
равно false.
Родительский onTouchEvent
принимается до onTouchEvent
ребенка. Если OnInterceptTouchEvent
возвращает значение false, он отправляет событие движения по цепочке в обработчик OnTouchEvent
дочернего OnTouchEvent
. Если он вернет true, родительский элемент обработает событие touch.
Однако могут быть случаи, когда мы хотим, чтобы некоторые дочерние элементы управляли OnTouchEvent
s, а некоторые из них управлялись родительским представлением (или, возможно, родителем родителя).
Это можно управлять несколькими способами.
- Одним из способов защиты дочернего элемента от родительского
OnInterceptTouchEvent
является реализация requestDisallowInterceptTouchEvent .
public void requestDisallowInterceptTouchEvent (boolean disallowIntercept)
Это не позволяет любому из родительских представлений управлять OnTouchEvent
для этого элемента, если элемент имеет обработчики событий.
Если OnInterceptTouchEvent
является ложным, будет оцениваться OnTouchEvent
дочернего элемента. Если у вас есть методы в дочерних элементах, обрабатывающих различные события касания, любые связанные обработчики событий, которые отключены, возвращают OnTouchEvent родительскому элементу.
Этот ответ:
Визуализация того, как проходит распространение сенсорных событий:
parent -> child|parent -> child|parent -> child views.
- Другой способ - вернуть переменные значения из
OnInterceptTouchEvent
для родителя.
Этот пример взят из Managing Touch Events в ViewGroup и демонстрирует, как перехватывать OnTouchEvent
ребенка при прокрутке пользователя.
4а.
@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;
}
Это код из той же ссылки, показывающий, как создать параметры прямоугольника вокруг вашего элемента:
4б.
// 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);
}