Обнаружение броска жеста по кликабельным предметам - PullRequest
23 голосов
/ 07 февраля 2012

Представьте макет с 4 кнопками

 _______________________________
|              |                |
|      A       |       B        |
|______________|________________|
|              |                |
|      C       |       D        |
|______________|________________|

Я хотел бы обнаружить жест броска по всему макету, но когда бросок начинается с кнопки, он не обнаруживается.

Я использую:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    gesturedetector= new GestureDetector(this, this);

    findViewById(R.id.touchContainer).setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Log.e("","TouchEvent");
            return gesturedetector.onTouchEvent(event);
        }
    });
}

Это когда нет интерактивных элементов, но происходит сбой, если бросок начинается поверх интерактивного элемента.

Как я могу решить это? Предлагая вознаграждение в 50 баллов за полный рабочий ответ

1 Ответ

27 голосов
/ 07 февраля 2012

Один из способов добиться этого - переопределить следующий метод:

public boolean onInterceptTouchEvent(MotionEvent event){
    super.onInterceptTouchEvent(event);
    ...

Вы можете переопределить этот метод в своем контейнере макета (например, ViewGroup, или что бы вы ни держали кнопки) и продолжитьвернуть false из него, чтобы «перехватить» сенсорные события, которые потребляются дочерними View s (т.е. вашими кнопками).В этом переопределенном методе вы можете затем вызвать свой объект детектора жестов с MotionEvent s.Этот метод также «видит» события, которые также нацелены на сам ViewGroup, что означает - если я правильно помню - вам нужно будет только вызвать ваш детектор жестов из этого метода, и при этомдетектор жестов будет «видеть» все события, независимо от того, находятся они над кнопками или нет.Поэтому, если вы проведете пальцем, начиная с кнопки, а затем заканчивая в какой-то момент на фоне макета, детектор жестов должен видеть весь удар.Вам не нужно будет подавать в детектор жестов события из собственного onTouchEvent() макета, потому что он уже видел их.

Второй способ:

Я просто посмотрел на свой проект, где я использовал это, и понял, что переключился на другой способ сделать это.На самом деле я разработал все свои дочерние элементы View так, чтобы родительский элемент Activity (или содержащий ViewGroup) мог зарегистрировать один и тот же объект детектора жестов со всеми этими дочерними элементами View (каждый из моихспециальные View имеют метод, называемый registerGestureDetector()).Затем в переопределенном onTouchEvent () моего ребенка View s я передаю MotionEvent s детектору жестов, который был зарегистрирован с этим View.Другими словами, родительский макет ViewGroup и все дочерние View просто используют один и тот же детектор жестов.

Я понимаю, что это может звучать немного хлопотно и не нужно, учитывая, что это можно сделать с помощью onInterceptTouchEvent(), но мое приложение имеет дело с некоторыми довольно сложными правилами относительно того, как мои View должны реагировать насенсорные события и жесты, и это позволило мне применить некоторую дополнительную логику, которая мне была нужна для моего приложения.Однако оба эти метода, которые я использовал, достигают одной и той же основной цели: направить MotionEvent s, нацеленные на различные View s, на один и тот же объект детектора жестов.

...