2012-08-10 35 views
1

我查看onTouch方法:ACTION_DOWN或仅ACTION_MOVE()

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永远不会同时发生。

你知道这个问题的解决方法吗?

在此先感谢,塞巴斯蒂安

回答

0

得到它的工作!

对于有同样的问题感到沉沦,随意采取此示例代码为帮助:)

的东西,我在开始的时候宣布

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-Method

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 { INT的x,y; int TYPE; boolean spotted; 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; 
} 

}

说明:

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

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

distanceMovedX & Y: 保存“ACTION_MOVE”的所有X和Y坐标。从pos 0(第一个触摸点)到pos Z(最后一个触摸点,其中发生ACTION_UP)。虽然它不是原来的X和Y位置。它是posZ - pos0的结果。 有了这些值,你可以确定,行驶了多长距离后,你想调用“onMove”和BELOW,应该调用哪个距离“onClick”。

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

方法:

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

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

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

就是这样。花了我几天的时间才找出这个选择; /羞愧的那个...虽然我编码它很快,让我感觉更好:D

+0

老实说,这不是完美的样本,因为任何其他移动事件(侧向或向上)都会被忽略。只需在ifMoveEvent()方法中添加另一个If-clause子句 - 方法 – JustBasti 2012-08-13 18:53:49

0

我只是提出一些-走动:

,而无需删除的点点击它的时候, 做出PRIVATA点在你的类,在那里你当前删除点,只要将新的变量指向你会删除点...

然后,在动作或动作移动使用后,最后的地方,你会使用它,如果 检查您的私人变量不为空,如果是这样,请将其删除,然后将其设置为空。

+0

谢谢,但没有解决我的问题。在我实际移动它之前,画布上的点仍然消失。 – JustBasti 2012-08-10 18:41:38

-1

尝试使用一个开关case语句:

开关finger_action:

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

记下了上面的代码是伪代码,但它做什么它会检查,如果你之前刚刚动点触摸它。通过这种方式,点将首先尝试移动,而不是先移除。

感谢, 亚历

+0

hmh,尝试了它,它使代码看起来更清晰,但它没有工作:(仍然,首先ACTION_DOWN出现,然后ACTION_MOVE和最后ACTION_UP。我认为没有办法改变这个序列。 – JustBasti 2012-08-10 19:53:59