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() в своем представлении, он должен обрабатывать события в этом представлении. Иногда их легко спутать.