Вы пробовали переопределить dispatchTouchEvent
?
https://developer.android.com/reference/android/view/View.html#dispatchTouchEvent(android.view.MotionEvent)
UPDATE:
Так что сенсорные события - это нечто чудовищное. Краткое изложение этого ...
- Сначала они всплывают из вашего корневого контейнера в вашей активности. Это делается путем вызова
dispatchTouchEvent
, а затем onInterceptTouchEvent
при условии, что перехват не был заблокирован дочерним представлением.
- Если ни одно представление не перехватывает событие, оно будет пузыриться до конечного узла (такого как кнопка), где вызывается
onTouch
. Если узел не обрабатывает его (возвращает true
), его родитель получает шанс и так далее.
Это означает, что вы можете использовать dispatchTouchEvent
или onInterceptTouchEvent
, чтобы шпионить за событиями касания без изменения поведения. Если вы на самом деле не собираетесь перехватывать событие, я предлагаю использовать dispatchTouchEvent
, поскольку он гарантированно будет выполняться, тогда как перехват может быть заблокирован (пример: DrawerLayout
будет перехватывать события касания у края, чтобы открыть ящик).
Итак, окончательный результат:
public class MyView extends Button {
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
Log.e("test", "ACTION_DOWN");
break;
case MotionEvent.ACTION_UP:
Log.e("test", "ACTION_UP");
break;
case MotionEvent.ACTION_CANCEL:
Log.e("test", "ACTION_CANCEL");
break;
}
return super.dispatchTouchEvent(event);
}
}
UPDATE:
Извините, поэтому у меня почему-то сложилось впечатление (в основном из-за моего плохого чтения), что мы имеем дело с родителем. Вот что я бы сделал ...
Продолжайте реализовывать onTouch
и возвращайте true
, чтобы поглотить все события. Это означает, что любые сенсорные события, которые начинаются на вашем экране, будут уничтожены. Затем мы переместим точку в координатное пространство родителя и вручную передадим событие касания, оно будет выглядеть так в вашем пользовательском представлении ...
private boolean passingTouchEventToParent = true;
final private Rect hitRect = Rect();
@Override
public boolean onTouch(MotionEvent event) {
// Handle your custom logic here
final ViewParent viewParent = getParent();
if (passingTouchEventToParent &&
viewParent != null &&
viewParent instanceof View) {
// Gets this view's hit rectangle in the parent's space
getHitRect(hitRect);
event.offsetLocation((float) hitRect.left, (float) hitRect.top);
passingTouchEventToParent = viewParent.onTouchEvent(event);
}
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
// Motion event finished, reset passingTouchEventToParent
passingTouchEventToParent = true;
}
return true;
}