Android初学者:理解MotionEvent事件动作

13

我在尝试生成一个 MotionEvent.ACTION_UP 时遇到了问题,可能是初学者的错误。

在 LogCat 中,我只看到 ACTION_MOVE 事件(一个整数值为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;
  }

}

rgr-mt在一份suggested edit中指出:“数字3代表ACTION_CANCEL,你可能是想用数字2(ACTION_MOVE)”。 - Michael Mrozek
2个回答

12

首先,您需要按照Webview教程的指示操作,以便让WebViewClient代替默认浏览器完成工作。如果没有这样做,在加载网页后,您将无法获取任何事件。

假设您希望在活动中处理事件,则可以添加dispatchTouchEvent方法:

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

您还将看到其他的触摸事件。您应该在此方法中处理它们。

另一种方法是注册一个事件监听器。您的类会变成:

public class Brand extends Activity implements OnTouchListener {

onCreate() 中做如下操作:

webview.setOnTouchListener(this);

将此添加到 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;

根据我的日志,我得到了以下内容:

  1. 首先调用dispatchTouchEvent()
  2. 然后调用onTouch()
  3. 然后视图获取事件以处理它
  4. 然后onTouchEvent()可能会收到事件 (见下文)

此外,onTouch() 的报告是相对于 View,dispatchTouchEvent() 的报告值是相对于 Display。

为什么 onTouchEvent() 没有报告这些事件?像许多这样的方法一样,onTouchEvent() 有两个版本。

如果在 Activity 中覆盖onTouchEvent(),则它将作为“万能钥匙” - 仅处理未被 View 消耗的事件,例如如果您在任何 View 之外点击,或者这些 View 传递的事件。如果在 View 中覆盖onTouchEvent(),则应该处理该 View 中的事件。有时很容易混淆两者。


10

你的问题是在WebView中执行此操作。WebViews具有内置的触摸控件,允许用户滚动页面,这可能会干扰接收MotionEvents。似乎你需要使用不同的View。例如,我刚刚运行了你的代码并进行了以下替换:

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

取代

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

并且其他所有的东西都正常工作。注意:我只是为了简单起见将TextView用作整个视图。这在像LinearLayouts、RelativeLayouts、带有画布的自定义视图等ViewGroup上可以正常工作。只是WebView似乎很特别。(当我使用WebView时,我只收到ACTION_MOVE事件。)所以,我希望你能尝试使用除了WebView之外的其他东西!


哇,谢谢回复!虽然会让事情变得有点复杂,但至少它将会工作! :) - Dave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接