Android - onTouchEvent仅在第一次工作

时间:2012-07-25 09:30:24

标签: java android ontouchevent

我有一个使用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;
}

8 个答案:

答案 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;
        }
    });
   }     
 }

这是示例Android Drag and drop images on the Screen?

答案 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处理程序处理......