onTouch中的ACTION_DOWN或仅ACTION_MOVE()

时间:2012-08-10 18:02:56

标签: java android android-canvas ontouchevent

我的观点的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为true时,我想移动该点,具体取决于event.getX()和event.getY()。

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

如果采取了这个位置(意味着,我只是点击了一个项目),我将进入motionevent-IFs。

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

你知道对此有任何解决方法吗?

提前谢谢,塞巴斯蒂安

3 个答案:

答案 0 :(得分:2)

让它发挥作用!

对于有同样问题的人,请随意将此示例代码作为帮助:)

我在开头宣布的东西

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

touchedPoint-方法

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

Point Class

class Point {     int x,y;     int TYPE;     布尔发现;     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&amp; Y: 保存“ACTION_MOVE”的所有X和Y坐标。从pos 0(第一个触摸点)到pos Z(最后一个触摸点,ACTION_UP发生的地方)。虽然它不是原来的X和Y位置。这是posZ - pos0的结果。 使用这些值,您可以确定,在您想要调用“onMove”之后的距离之后,以及应该调用“onClick”的距离。

mNewX&amp; Y: onTouch-Method的当前位置。每当你移动手指时,newX&amp; Y被覆盖。

方法:

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

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

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

多数民众赞成。花了我几天时间才弄清楚那个选项; /感到惭愧......虽然我把它编得很快,但是让我感觉好些了:D

答案 1 :(得分:0)

我只是建议一些走动:

点击时不删除点, 在你的班级中创建一个privata Point,你当前删除该点,只需将你的新变量点设置为你要删除的点......

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

答案 2 :(得分:-1)

尝试使用switch case语句:

切换finger_action:

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

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

感谢, 亚历