Android-новичок: понимание действий MotionEvent

У меня возникли проблемы с получением моей активности для создания MotionEvent.ACTION_UP. Вероятно, ошибка начинающего.

В LogCat я вижу событие ACTION_MOVE (значение int 3). Я также вижу координаты X/Y. Нет ACTION_DOWN и ACTION_UP.

Я везде искал решение. Я нашел один вопрос на форуме, который, похоже, совпадает с моей проблемой, но решение не предлагается: http://groups.google.com/group/android-developers/browse_thread/thread/9a9c23e40f02c134/bf12b89561f204ad?lnk=gst&q=ACTION_UP#bf12b89561f204ad

Здесь мой код:

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.webkit.WebView;

public class Brand extends Activity {

public WebView webview;
public float currentXPosition;
public float currentYPosition;

@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);

    webview = new WebView(this);
    setContentView(webview);
    webview.loadUrl("file:///android_asset/Brand.html");


 }

@Override
public boolean onTouchEvent(MotionEvent me) {

    int action = me.getAction();
    currentXPosition = me.getX();
    currentYPosition = me.getY();

    Log.v("MotionEvent", "Action = " + action);
    Log.v("MotionEvent", "X = " + currentXPosition + "Y = " + currentYPosition);

    if (action == MotionEvent.ACTION_MOVE) {
         // do something
    }


    if (action == MotionEvent.ACTION_UP) {
         // do something
    }

    return true;
  }

}

Ответы

Ответ 1

Ваша проблема в том, что вы делаете это изнутри WebView. WebViews имеют встроенное сенсорное управление, позволяющее пользователю прокручивать страницу вокруг, и это должно мешать вам получать MotionEvents. Казалось бы, вам нужно будет использовать другой вид. Например, я просто запустил ваш код, выполнив следующую подстановку:

TextView tv = new TextView(this);
setContentView(tv);

вместо

webview = new WebView(this);
setContentView(webview);
webview.loadUrl("file:///android_asset/Brand.html");

и все остальное работало. Примечание. Я использовал TextView в качестве всего представления просто для простоты. Это работает на ViewGroups, например LinearLayouts, RelativeLayouts, пользовательских представлениях с холстами и т.д. Просто кажется, что WebViews являются особенными. (Я также получал ACTION_MOVE при использовании WebView.) Поэтому я надеюсь, что вы можете уйти от использования чего-то другого, кроме WebView!

Ответ 2

Сначала вам нужно следовать учебнику Webview, чтобы WebViewClient вместо браузера по умолчанию выполните эту работу. Без этого, после загрузки веб-страницы, вы не получите никаких событий вообще.

Предполагая, что вы хотите обрабатывать события в своей активности, вы можете добавить метод dispatchTouchEvent:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    Log.v("FROM_DISPATCH_TOUCH_EVENT", "Action = " + ev.getAction());
    return false; 
}

Вы также увидите другие события касания. Вы должны обрабатывать их в этом методе.

Альтернативный подход - зарегистрировать EventListener. Ваш класс станет следующим:

public class Brand extends Activity implements OnTouchListener {

в onCreate() сделать это:

webview.setOnTouchListener(this);

a добавьте это в Activity:

@Override
public boolean onTouch(View v, MotionEvent event) {
   int action = event.getAction();
    float x = event.getX();
    float y = event.getY();

    Log.v("ON_TOUCH", "Action = " + action + " View:" + v.toString());
    Log.v("ON_TOUCH", "X = " + x + "Y = " + y);

return false;

}

Из моих журналов я получаю следующее:

  • dispatchTouchEvent() вызывается первым
  • Затем onTouch() называется
  • Затем представление получает событие, чтобы обработать его
  • Затем onTouchEvent() может получать события (см. ниже)

Кроме того, onTouch() сообщает относительно представления, dispatchTouchEvent() сообщает значения относительно отображения.

Почему onTouchEvent не сообщает об этих событиях? Как и многие из этих методов, существуют два воплощения onTouchEvent().

Если вы переопределяете onTouchEvent() в своей деятельности, он служит как "catch all" - он обрабатывает только те события, которые не были использованы с помощью представлений, например, если вы выходите за пределы какого-либо вида или события, которые проходят эти Представления. Если вы переопределите onTouchEvent() в своем представлении, он должен обрабатывать события в этом представлении. Иногда их легко спутать.