2012-07-25 217 views
1

我有一個使用OnTouch的畫布繪圖,但由於某種原因,我無法使其正常工作。它第一次運作(第一次觸摸運動)。但是,當用戶移開他的手指時,OnTouch再也不會再次運行,停止用戶移動角色項目。Android - onTouchEvent只能第一次工作

經過大量的研究和各種不同的選擇,我簡直無法得到這個工作,並在這樣做注意到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

從開關案例中刪除MotionEvent.ACTION_MASK – AkashG 2012-07-25 09:32:09

+0

@AkashG,試過,但沒有工作還有其他想法嗎? – 2012-07-25 09:38:20

+0

你的意思是說,當用戶第一次做ACTION_DOWN + MOVE + UP它確定,但下次不起作用?第二次輸入MOVE並拖動是否等於true? – Dayerman 2012-07-25 09:59:04

回答

0

看起來像面具和您在交換機上應用的事件有問題。看看這個issue

+0

請參閱我修正的onTouch代碼(這仍然無法正常工作)。 – 2012-11-24 14:08:09

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?

+0

請參閱我修正的onTouch代碼(這仍然無法正常工作)。 – 2012-11-24 14:11:17

2

我非常確信你Touch被稱爲每次,我懷疑可能是你的情況下,原因不符合要求。

交叉檢查只是把日誌打印

@Override 
public boolean onTouchEvent(MotionEvent event) 
{ 
    System.out.println("Touch working"); 
    return false; 
} 
+0

是的,我似乎每次移動或觸摸屏幕時都會調用它。如果我將用戶向下移動3個空格,它會被調用3次,那麼如何修復我的上面的代碼,以便它可以像應該那樣工作? THanks – 2012-11-23 11:11:12

+0

請參閱我修正的onTouch代碼(這仍然無法正常工作)。 – 2012-11-24 13:50:59

1

試圖改變最終返回真不假 就像是:

@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 
} 
+0

不幸在嘗試之前仍然無法正常工作。 – 2012-11-23 11:48:27

+0

請參閱我修正的onTouch代碼,儘管我已將結束返回更改回false(儘管如此,仍然無法正常工作)。 – 2012-11-24 14:09:33

0

的主要問題是,你缺少break語句在每個案件結束時。 您會遇到其他情況並在第二個ACTION_DOWN上返回false。這意味着ACTION_UP和MOVE不會被調用。

要解決這個問題: - 在每一種情況下 的末尾添加break語句 - 始終從ACTION_DOWN

+0

請參閱我修正的onTouch代碼(這仍然無法正常工作)。 – 2012-11-24 14:08:39

+0

嘗試始終從ACTION_DOWN返回true。如果您返回false,您將永遠不會收到要求移動或打開的電話。您需要調試:在代碼中添加日誌消息,並查看您到達的位置以及您無法訪問的位置。 – yoah 2012-11-25 14:44:46

0

返回true,不返回true,但假的。

if(Math.floor(touchX/totalCellWidth) == currentX && Math.floor(touchY/totalCellHeight) == currentY) 
{ 
    dragging = true; 
    return false; 
} 
+0

如果返回false,則會完全中斷代碼,並且第一次觸摸不再起作用。任何其他想法?謝謝 – 2012-11-26 12:25:28

0

put return = true;而不是在您的開關盒的最後陳述中爲false。因爲如果使用虛假比它會調用僅一次,然後沒有其他的觀點可以得到特定視圖的觸摸事件..所以使用真實的,而不是假的..

理論
在的onTouchEvent返回true( )告訴Android系統您已經處理了觸摸事件,不需要進一步處理。如果您返回false,則Android系統將成爲onTouch事件的處理程序,並將覆蓋您通過ACTION_DOWN(這是您觸摸屏幕時的第一個事件)的任何事件的代碼。

我也有同樣的問題,現在解決了。我認爲它可以幫助你..

+0

我現在在我的switch語句結尾處返回true,但是我仍然遇到同樣的問題。請在我的問題中查看我修正的onTouch代碼。謝謝 – 2012-11-26 12:02:42

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處理程序...

+0

嗨,我已經修改我的代碼與上述mentioend相同的方式,但它仍然無法正常工作。我在這裏添加了我的新的onTouch代碼和錯誤日誌http://pastebin.com/mbn8mZ8g。我還在日誌中添加了currentX&Y。最後,需要注意的是,我的onTouch涉及到迷宮,基本上迷宮是100x100,但是隻有5x5才顯示,因此當用戶移動時,由於它們在迷宮中的位置,當前的X和Y被改變(這可能會影響onTouch )。如果我們能在接下來的4個小時內完成排序,那麼我可以正確地向您頒發獎金。謝謝 – 2012-11-27 11:17:34