【问题标题】:Android onTouch() method doesn't work (swipe detection)Android onTouch() 方法不起作用(滑动检测)
【发布时间】:2017-11-07 12:06:01
【问题描述】:

我正在使用 Android Studio 2.3.2 在 Android 上对 Snake 进行编程

为了移动蛇,我制作了一个 onTouchListener 来检测用户是否在滑动以及朝哪个方向(北、南、东、西)滑动

下面是View.onTouchListener的onTouch方法:

@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            prevX = event.getX();
            prevY = event.getY();

            break;
        case MotionEvent.ACTION_UP:
            float newX = event.getX();
            float newY = event.getY();


            //Calculates where we swiped

            if (Math.abs(newX - prevX) > Math.abs(newY - prevY)) {
                //LEFT - RiGHT Direction

                if( newX > prevX) {
                    //RIGHT
                    gameEngine.updateDirection(Direction.East);
                } else {
                    //LEFT
                    gameEngine.updateDirection(Direction.West);
                }
            } else {
                // UP-DOWN Direction
                if (newY > prevY) {
                    //DOWN
                    gameEngine.updateDirection(Direction.South);
                } else {
                    //UP
                    gameEngine.updateDirection(Direction.North);
                }
            }

            break;
    }
    return false;
}

问题在于它只检测 LEFT 和 RIGHT(即 EAST 和 WEST)。 而且我不知道为什么没有检测到 UP 和 DOWN。

【问题讨论】:

  • 这与你的 onTouchListener() 无关,你的计算不符合要求。 if (Math.abs(newX - prevX) > Math.abs(newY - prevY)) 似乎总是正确的。第二种情况,newY>prevY 然后newY 总是更大....
  • @Opiatefuchs 好的,问题是我不明白为什么它总是正确的,因为当我沿 y 轴滑动时,它应该比 x 轴具有更高的值。因为我在 x 轴上向上/向下滑动时的差异应该接近于零。
  • 通常您只需比较 x 轴的 prevX 和 newX 以及 prevY 和 newY。为什么要比较 x 轴和 y 轴?

标签: android 2d android-canvas ontouchlistener ontouch


【解决方案1】:

试试下面的代码。它对我有用。

Java:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class MainSnake extends AppCompatActivity implements View.OnTouchListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_snake);
        findViewById(R.id.main_view).setOnTouchListener(this);
    }


    float prevX, prevY;
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                prevX = event.getX();
                prevY = event.getY();

                return true;
            case MotionEvent.ACTION_UP:
                float newX = event.getX();
                float newY = event.getY();


                //Calculates where we swiped

                if (Math.abs(newX - prevX) > Math.abs(newY - prevY)) {
                    //LEFT - RiGHT Direction

                    if( newX > prevX) {
                        //RIGHT
                        Log.i("TOUCH INFO", "Right");
                    } else {
                        //LEFT
                        Log.i("TOUCH INFO", "Left");
                    }
                } else {
                    // UP-DOWN Direction
                    if (newY > prevY) {
                        //DOWN
                        Log.i("TOUCH INFO", "Down");
                    } else {
                        //UP
                        Log.i("TOUCH INFO", "Up");
                    }
                }

                break;
        }
        return false;
    }
}

XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/main_view">

</android.support.constraint.ConstraintLayout>

【讨论】:

  • 确保你的布局被命名为 activity_main_snake 或者相应地改变它。
  • 它有效,我可以看到他认出了我的动作,但现在我需要再次将蛇视图添加到您的约束布局中
  • 谢谢你,但你是对的,我之前的版本是对的,我发现方法“updateDirection()”中的错误我真的很抱歉,但这是第一次在二维和处理程序等,现在对我来说非常重要^^
  • 很高兴为您提供帮助!祝你好运。
【解决方案2】:

您必须在 ACTION_DOWN 之后返回“True”。这告诉 Android 监视 ACTION_UP 事件。

switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        prevX = event.getX();
        prevY = event.getY();

        return true;

【讨论】:

  • 它之前观察过 ACTION_UP 事件(左右方向都有效),即使我像你提到的那样编辑代码,它也没有任何改变。
  • 我测试了代码,它对我有用。所以逻辑是对的。也尝试测试 ACTION_CANCEL。也许视图不够大,无法检测到每个方向。
  • 我在最后添加了 (case MotionEvent.ACTION_CANCEL: break;) 但它仍然不起作用。我正在 720p 屏幕上测试应用,应该有足够的空间。
  • 您要将事件测试添加到哪种类型的视图中?确保它不与其他视图冲突。就像我上面说的,我有你的代码的工作示例。所以比较逻辑是合理的。
  • 我制作了一个 SnakeView,它添加了这个 onTouchListener 并且我没有任何其他视图。
猜你喜欢
  • 2015-01-09
  • 2014-05-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
  • 2013-02-24
  • 1970-01-01
相关资源
最近更新 更多