Android初学者:了解MotionEvent动作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2609114/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:32:42  来源:igfitidea点击:

Android beginner: understanding MotionEvent actions

android

提问by Dave

I am having trouble getting my activity to generate a MotionEvent.ACTION_UP. Probably a beginner's error.

我无法让我的活动生成 MotionEvent.ACTION_UP。可能是初学者的错误。

In LogCat, I'm only seeing the ACTION_MOVE event (which is an int value of 3). I also see the X/Y coordinates. No ACTION_DOWN and no ACTION_UP.

在 LogCat 中,我只看到 ACTION_MOVE 事件(int 值为 3)。我还看到了 X/Y 坐标。没有 ACTION_DOWN 也没有 ACTION_UP。

I looked everywhere for a solution. I found one question on a forum that seems to be the same as my issue, but no solution is proposed: http://groups.google.com/group/android-developers/browse_thread/thread/9a9c23e40f02c134/bf12b89561f204ad?lnk=gst&q=ACTION_UP#bf12b89561f204ad

我到处寻找解决方案。我在论坛上发现一个问题,似乎与我的问题相同,但没有提出解决方案:http: //groups.google.com/group/android-developers/browse_thread/thread/9a9c23e40f02c134/bf12b89561f204ad?lnk=gst&q =ACTION_UP#bf12b89561f204ad

Here's my code:

这是我的代码:

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;
  }

}

采纳答案by Steve Haley

Your problem is that you're doing this from within a WebView. WebViews have built-in touch control to allow the user to scroll the page around, and that must be interfering with you receiving the MotionEvents. It would seem that you will need to use a different View. For example, I just ran your code making the following substitution:

您的问题是您是在 WebView 中执行此操作的。WebViews 有内置的触摸控制,允许用户滚动页面,这肯定会干扰你接收 MotionEvents。您似乎需要使用不同的视图。例如,我只是运行您的代码进行以下替换:

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

instead of

代替

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

and everything else worked. Note: I used a TextView as the whole view just for simplicity. This works on ViewGroups like LinearLayouts, RelativeLayouts, custom Views with canvases etc. It just seems that WebViews are special. (I was also only receiving ACTION_MOVE when using the WebView.) So, I hope you can get away with using something other than a WebView!

其他一切都奏效了。注意:为了简单起见,我使用 TextView 作为整个视图。这适用于 ViewGroups,如 LinearLayouts、RelativeLayouts、带有画布的自定义 Views 等。看起来 WebViews 很特别。(我在使用 WebView 时也只收到 ACTION_MOVE。)所以,我希望您可以使用 WebView 以外的其他东西!

回答by rgr_mt

First you need to follow the Webview tutorialto let a WebViewClientinstead of the default browser do the work. Without that, after you load a web page, you would not get any events at all.

首先,您需要按照Webview 教程WebViewClient而不是默认浏览器来完成工作。没有它,在您加载网页后,您根本不会收到任何事件。

Assuming you want to handle the events in your acrtivity you can add the method dispatchTouchEvent:

假设您要处理活动中的事件,您可以添加方法dispatchTouchEvent

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

You will see the other touch events as well. You should handle them in this method.

您还将看到其他触摸事件。你应该用这种方法处理它们。

An alternative approuch is to register an EventListener. Your class would become:

另一种方法是注册一个 EventListener。你的班级会变成:

public class Brand extends Activity implements OnTouchListener {

in onCreate()do this:

onCreate() 中这样做:

webview.setOnTouchListener(this);

an add this to the 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;

}

}

From my logs I then get the following:

从我的日志中,我得到以下信息:

  1. dispatchTouchEvent()is called first
  2. Then onTouch()is called
  3. Then the View gets the Event to handle it
  4. Then onTouchEvent()might get events (see below)
  1. dispatchTouchEvent()首先被调用
  2. 然后onTouch()被调用
  3. 然后视图获取事件来处理它
  4. 然后onTouchEvent()可能会得到事件(见下文)

Moreover, onTouch()reports relative to the View, dispatchTouchEvent()reports values relative to the Display.

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

Why does onTouchEvent not report these Events? Like many of these methods there are two incarnations of onTouchEvent().

为什么 onTouchEvent 不报告这些事件?像许多这些方法一样,onTouchEvent()有两个化身。

If you override onTouchEvent()in your Activity it serves as a "catch all" - it only handles the events that have not been consumed by the Views, for example if you tap outside of any View, or the events these Views pass on. If you override onTouchEvent()in your View it it supposed to handle the events in that View. Sometimes it is easy to confuse the two.

如果您在您的 Activity 中覆盖onTouchEvent(),它会充当“一网打尽”——它只处理未被视图使用的事件,例如,如果您点击任何视图之外的事件,或者这些视图传递的事件。如果您在视图中覆盖onTouchEvent()它应该处理该视图中的事件。有时很容易混淆两者。