我有一个使用OnTouch的画布图,但由于某种原因我无法使其正常工作。它是第一次工作(第一次触摸运动)。但是,当用户移开手指时,OnTouch永远不会再次运行,从而阻止用户移动角色项目。
经过大量的研究和各种不同的选择后,我根本无法让它工作,并且这样做已经注意到第一次调用ACTION_DOWN然后调用ACTION_UP。
下面你可以找到我的2块代码,第一个是实际的onTouchEvent。第二个用于在我绘制的画布中处理用户权限的代码块(基于迷宫(5 x 5))。
另一个需要考虑的问题是每次移动用户位置时画布都会被重绘(无效)(这是逐个方块完成的)
@Override
public boolean onTouchEvent(MotionEvent event)
{
float touchX = event.getX();
float touchY = event.getY();
int currentX = maze.getCurrentX();
int currentY = maze.getCurrentY();
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
if(Math.floor(touchX/totalCellWidth) == currentX && Math.floor(touchY/totalCellHeight) == currentY)
{
dragging = true;
return true;
}
break;
case MotionEvent.ACTION_UP:
dragging = false;
break;
case MotionEvent.ACTION_MOVE:
if(dragging)
{
int cellX = (int)Math.floor(touchX/totalCellWidth);
int cellY = (int)Math.floor(touchY/totalCellHeight);
if((cellX != currentX && cellY == currentY) || (cellY != currentY && cellX == currentX))
{
boolean moved = false;
switch(cellX-currentX)
{
case 1:
moved = maze.move(Maze.RIGHT);
break;
case -1:
moved = maze.move(Maze.LEFT);
}
switch(cellY-currentY)
{
case 1:
moved = maze.move(Maze.DOWN);
break;
case -1:
moved = maze.move(Maze.UP);
}
if(moved)
{
invalidate();
if(maze.isGameComplete())
{
showFinishDialog();
}
}
}
break;
}
}
return true;
}
迷宫位置处理程序代码:
public boolean move(int direction)
{
boolean moved = false;
if(direction == UP)
{
if(currentY != 0 && !horizontalLines[currentY-1][currentX])
{
currentY--;
moved = true;
}
}
if(direction == DOWN)
{
if(currentY != verticalLines[0].length-1 && !horizontalLines[currentY][currentX])
{
currentY++;
moved = true;
}
}
if(direction == RIGHT)
{
if(currentX != horizontalLines[0].length-1 && !verticalLines[currentY][currentX])
{
currentX++;
moved = true;
}
}
if(direction == LEFT)
{
if(currentX != 0 && !verticalLines[currentY][currentX-1])
{
currentX--;
moved = true;
}
}
if(moved)
{
if(currentX == finalX && currentY == finalY)
{
gameComplete = true;
}
}
return moved;
}
答案 0 :(得分:1)
尝试将最终返回更改为True而不是False 像那样:
@Override
public boolean onTouchEvent(MotionEvent event)
{
float touchX = event.getX();
float touchY = event.getY();
int currentX = maze.getCurrentX();
int currentY = maze.getCurrentY();
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
{
if(Math.floor(touchX/totalCellWidth) == currentX &&Math.floor(touchY/totalCellHeight) == currentY)
{
dragging = true;
return true;
}
}
case MotionEvent.ACTION_UP:
dragging = false;
return true;
case MotionEvent.ACTION_MOVE:
if(dragging)
{
int cellX = (int)Math.floor(touchX/totalCellWidth);
int cellY = (int)Math.floor(touchY/totalCellHeight);
if((cellX != currentX && cellY == currentY) || (cellY != currentY && cellX == currentX))
{
//either X or Y changed
boolean moved = false;
//check horizontal ball movement
switch(cellX-currentX)
{
case 1:
moved = maze.move(Maze.RIGHT);
break;
case -1:
moved = maze.move(Maze.LEFT);
}
//check vertical ball movement
switch(cellY-currentY)
{
case 1:
moved = maze.move(Maze.DOWN);
break;
case -1:
moved = maze.move(Maze.UP);
}
if(moved)
{
invalidate();
if(maze.isGameComplete())
{
showFinishDialog();
}
}
}
return true;
}
}
return True; // Here
}
答案 1 :(得分:0)
看起来像Mask的问题以及您在交换机上应用的事件。看看这个issue
答案 2 :(得分:0)
这里有触摸的好例子可能是有用的不确定吗?
public boolean onTouch(View v, MotionEvent event) {
layoutParams = (RelativeLayout.LayoutParams) ima1.getLayoutParams();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int x_cord = (int) event.getRawX();
int y_cord = (int) event.getRawY();
System.out.println("value of x" +x_cord);
System.out.println("value of y" +y_cord);
if (x_cord > windowwidth) {
x_cord = windowwidth;
}
if (y_cord > windowheight) {
y_cord = windowheight;
}
layoutParams.leftMargin = x_cord-25;
layoutParams.topMargin = y_cord-25;
// layoutParams.rightMargin = x_cord-25;
// layoutParams.bottomMargin = y_cord-25;
ima1.setLayoutParams(layoutParams);
break;
default: break;
}
return true;
}
});
ima2 = (ImageView)findViewById(R.id.imageview2);
ima2.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
layoutParams = (RelativeLayout.LayoutParams) ima2.getLayoutParams();
switch(event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int x_cord = (int) event.getRawX();
int y_cord = (int) event.getRawY();
System.out.println("value of x1" +x_cord);
System.out.println("value of y1" +y_cord);
if (x_cord > windowwidth) {
x_cord = windowwidth;
}
if (y_cord > windowheight) {
y_cord = windowheight;
}
layoutParams.leftMargin = x_cord - 25;
layoutParams.topMargin = y_cord - 75;
ima2.setLayoutParams(layoutParams);
break;
default: break;
}
return true;
}
});
}
}
答案 3 :(得分:0)
我非常确定您的Touch
每次都被调用,我怀疑您的案例可能不符合要求。
交叉检查只需输入日志
@Override
public boolean onTouchEvent(MotionEvent event)
{
System.out.println("Touch working");
return false;
}
答案 4 :(得分:0)
主要问题是你在每个案例结束时都缺少一个break语句。 你会遇到其他情况,并在第二个ACTION_DOWN返回false。这意味着不会调用ACTION_UP和MOVE。
解决这个问题: - 在每个案例结尾添加一个break语句 - 始终从ACTION_DOWN返回true
答案 5 :(得分:0)
不要返回true,而是返回false。
if(Math.floor(touchX/totalCellWidth) == currentX && Math.floor(touchY/totalCellHeight) == currentY)
{
dragging = true;
return false;
}
答案 6 :(得分:0)
在你的switch case的最后一个语句中输入 return = true; 而不是false。因为如果你使用false而不是只调用一次,那么没有其他视图可以获得该特定视图的触摸事件..所以使用true而不是false ..
<强>理论强>
在onTouchEvent()中返回true告诉Android系统您已经处理了触摸事件,并且不需要进一步处理。如果您返回false,Android系统将成为onTouch事件的处理程序,并将覆盖ACTION_DOWN之后的任何事件的代码(这是您触摸屏幕时的第一个事件)。
我也有同样的问题,现在已经解决了。我认为它可能对你有所帮助..
答案 7 :(得分:0)
我认为有问题的部分就是这个
event.getAction() & MotionEvent.ACTION_MASK
但再看一遍,似乎没问题......尝试用
替换它 event.getMaskedAction()
并将其保留在开关中。
或者您可能需要使用ACTION_POINTER_UP而不是ACTION_UP。
请问这段代码可以改变吗?
case MotionEvent.ACTION_MOVE:
Log.d(LOGTAG, "ACTION_MOVE block, dragging = "+dragging);
if(dragging)
{
Log.d(LOGTAG, "Dragging fired with event: "+event.toString());
int cellX = (int)Math.floor(touchX/totalCellWidth);
int cellY = (int)Math.floor(touchY/totalCellHeight);
// ...
请发布输出。
编辑:另外,请记住,只有当你想要完全使用事件时,才想从onlistener返回true;如果要进一步传播,则返回false。所以我想只有其中一个回归必须是真的,让别人传下来并由他们各自的观点'ontouch处理程序处理......