2

我的视图的 onTouch 方法:

public boolean onTouch(View view, MotionEvent event) {
        Log.d("Touch", "Touch");

        int mNewX = (int) Math.floor(event.getX());
        int mNewY = (int) Math.floor(event.getY());

        boolean isPositionFree = isPositionFree(mNewX, mNewY);

        if (!isPositionFree) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                int i = 0;
                for (Point point : points) { 
                    if (point.spotted) {
                        points.remove(i);
                        invalidate();
                        break;
                    }
                    i++;
                }
            } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                int i = 0;
                for (Point point : points) { 
                    if (point.spotted) {
                        points.remove(i);
                        Point p = new Point(mNewX, mNewY, point.TYPE);
                        points.add(i, p);
                        invalidate();
                        break;
                    }
                    i++;
                }
            }
        }
}

画布中有多个项目。他们的位置保存在“点”中。它们通过这些“点”的位置在 onDraw 方法中被绘制到画布上,即 Point point.x 和 point.y。

现在,当我单击一个项目(画布上的一个点)时,它应该会消失。然后,当 MotionEvent.ACTION_MOVE 为真时,我想移动点,具体取决于 event.getX() 和 event.getY()。

方法“isPositionFree(newX,newY)”检查 point.x 和 point.y 是否等于 newX 和 newY(我刚刚在屏幕上触摸的位置)。

如果该位置被占用(意味着我刚刚单击了一个项目),我将进入motionevent-IFs。

问题来了:我的代码在我实际移动它之前删除了该点。我没有找到任何方法可以解决这个问题几个小时。:/ 我觉得很难,因为 onTouch 总是从一开始就被调用,这意味着 ACTION_DOWN 和 ACTION_MOVE 永远不会同时发生。

你知道有什么解决办法吗?

在此先感谢,塞巴斯蒂安

4

3 回答 3

3

让它工作!

对于遇到相同问题的每个人,请随时将此示例代码作为帮助:)

我一开始声明的东西

Vector<Point> points = new Vector<Point>();

Bitmap[] monsterTypes = new Bitmap[3];

Vector<Integer> distanceMovedX = new Vector<Integer>();
Vector<Integer> distanceMovedY = new Vector<Integer>();

int mNewX = -1;
int mNewY = -1;

OnTouch 方法

public boolean onTouch(View view, MotionEvent event) {

        mNewX = (int) FloatMath.floor(event.getX());
        mNewY = (int) FloatMath.floor(event.getY());

        boolean touchedPoint = touchedPoint(mNewX, mNewY);

        switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:

            distanceMovedX.add(mNewX);
            distanceMovedY.add(mNewY);
            break;
        case MotionEvent.ACTION_UP:

            isMoveEvent = isMoveEvent();
            if (isMoveEvent) {
                for (Point point : points) {

                    if (point.spotted) {

                        // Your code
                    } 
                    i++;
                }
            } else {
                if (touchedPoint) {
                    for (Point point : points) { 
                        if (point.spotted) {

// Your code
                        }
                    }
                }
            }
            distanceMovedX.clear();
            distanceMovedY.clear();
            return true;
        }
        return true;
    }

接触点法

public boolean touchedPoint(int mNewX, int mNewY) {
        boolean touchedPoint = false;
        int height = 0;
        int width = 0;

        for (Point point : points) {
            height = monsterTypes[point.TYPE - 1].getHeight();
            width = monsterTypes[point.TYPE - 1].getWidth();

            if (point.x + width < mNewX || point.x > mNewX + width
                    || point.y + height < mNewY || point.y > mNewY + height) {
                touchedPoint = false;
                point.spotted = false;
            } else {
                touchedPoint = true;
                point.spotted = true;
                return touchedPoint;
            }
        }
        return touchedPoint;
    }

isMoveEvent-方法

public boolean isMoveEvent() {
        boolean isMoveEvent = false;
        boolean isMoveEventX = false;
        boolean isMoveEventY = false;

        for (int i = 0; i <= (points.size() -1); i++) {
            Log.d("point", "for loop entered");

            if (!distanceMovedY.isEmpty()) {
                Log.d("point.x", "distanceMovedY is not empty");
                int dMY = distanceMovedY.get(distanceMovedY.size() - 1) - distanceMovedY.get(0);

                if ((dMY > 50 || dMY <= 0) && dMY != 0) {
                    Log.d("point.y", "is move event");
                    Log.d("point.y", "dMY: " + dMY);
                    isMoveEventY = true;
                } else {
                    Log.d("point.x", "is no move event");
                    Log.d("point.x", "dMY: " + dMY);
                    isMoveEvent = false;
                    return isMoveEvent;
                }
            }
            if (!distanceMovedX.isEmpty()) {
                Log.d("point.x", "distanceMovedX is not empty");
                int dMX = distanceMovedX.get(distanceMovedX.size() - 1) - distanceMovedX.get(0);

                if (dMX <= 50 && dMX >= -50 && dMX != 0) {
                    Log.d("point.x", "is move event");
                    Log.d("point.x", "dMX: " + dMX);
                    isMoveEventX = true;
                } else {
                    Log.d("point.x", "is no move event");
                    Log.d("point.x", "dMX: " + dMX);
                    isMoveEvent = false;
                    return isMoveEvent;
                }
            }
            if (isMoveEventX && isMoveEventY) {
                Log.d("point", "is move event");
                isMoveEvent = true;
                return isMoveEvent;
            }
        }
        Log.d("point", "is no move event");
        return isMoveEvent;
    }

点类

类点 { int x, y; 整数类型;布尔值;boolean halfSpotted;

public Point() {
}

public Point(int x, int y, int t) {
    this.x = x;
    this.y = y;
    this.TYPE = t;
}

@Override
public String toString() {
    return x + ", " + y;
}

}

解释:

点:我们得到了一个班级点。Vector 中声明的所有这些点都是画布上的 x 和 y 坐标。他们帮助我们检查我们点击的位置。

MonsterTypes:它是我使用的不同图形。如果您只使用在画布上绘制的一个图形,请将其更改为您的需要

distanceMovedX & Y:保存“ACTION_MOVE”的所有 X 和 Y 坐标。从 pos 0(第一个接触点)到 pos Z(最后一个接触点,ACTION_UP 发生的地方)。虽然它不是原来的 X 和 Y 位置。它是 posZ - pos0 的结果。使用这些值,您可以确定在经过多远的距离后要调用“onMove”,然后在以下距离应调用“onClick”。

mNewX & Y:onTouch-Method 的当前位置。每次您移动手指时,newX 和 Y 都会被覆盖。

方法:

onTouch():首先,我们将 mNewX 和 Y 覆盖到当前触摸的位置。然后我们检查我们是否点击了一个现有的点(在我的例子中是一些 48px*48px 的区域)接下来我们在 ACTION_MOVE 中记录所拍摄的距离。之后,我们继续 ACTION_UP,检查我们是否刚刚执行了一些 moveEvent 或 clickEvent。

touchPoint():计算我们是否触摸了画布上的某个现有点。返回真或假

isMoveEvent():检查我们是否移动了一定距离。就我而言,我想向下移动 50 像素或更多。虽然我不允许向侧面移动 -50px 或 +50px。如果它不是移动事件,则最后触摸的点仍然必须在给定距离内(在我的情况下,在该点的 48px*48px 范围内)。

就是这样。我花了好几天才弄清楚那个选项;/为此感到羞耻......虽然我编码得很快,但是是什么让我再次感觉更好:D

于 2012-08-12T22:24:36.097 回答
0

我只是建议一些走动:

单击它时不要删除该点,而是在您当前删除该点的班级中创建一个私有点,只需将您的新变量点设置为您将删除的点...

然后,在 action 或 action move 中使用它后,最后一个使用它的地方,检查你的私有变量是否不为 null,如果是,则将其删除,然后将其设置为 null。

于 2012-08-10T18:25:39.520 回答
-1

尝试使用 switch case 语句:

切换手指动作:

case(ACTION_MOVE)
{
//move code
return false;
}
case(ACTION_TOUCH)
{
//dissappear code
return false;
}

注意上面的代码是伪代码,但它会检查你是否在触摸它之前移动点。这样,点将首先尝试移动,而不是首先被移除。

谢谢,亚历克斯

于 2012-08-10T18:53:31.693 回答