2

OnTouch を使用しているキャンバス描画がありますが、何らかの理由でこれを正しく動作させることができません。初めて動作します(ファーストタッチ動作)。ただし、ユーザーが指を離すと、OnTouch が再び実行されることはなく、ユーザーはキャラクター アイテムを動かすことができなくなります。

多くの調査とさまざまなオプションを行った結果、これを機能させることができず、ACTION_DOWN が初めて呼び出され、次に ACTION_UP が呼び出されることに気付きました。

以下に私の 2 つのコード チャンクを示します。最初のチャンクは実際の onTouchEvent です。2 つ目は、描画されたキャンバス (迷路 (5 x 5) ベース) 内でユーザーのアクセス許可を処理するために使用されるコードのチャンクです。

考慮すべきもう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;
                }
                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;
}
4

8 に答える 8

1

最終リターンを False ではなく True に変更しようとしています。

@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 
 }
于 2012-11-23T11:38:32.947 に答える
0

マスクとスイッチに適用しているイベントに問題があるようです。この問題をご覧ください

于 2012-07-25T12:25:19.970 に答える
0

here is good example of on touch may be it is usefull not sure?

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

this is example Android Drag and drop images on the Screen?

于 2012-11-20T05:17:12.983 に答える
0

リターン=真を入れてください。switch ケースの最後のステートメントで false の代わりに。false を使用すると、1 回だけ呼び出され、他のビューはその特定のビューのタッチ イベントを取得できないため、false の代わりに true を使用します。

理論
onTouchEvent() で true を返すと、Android システムに、既にタッチ イベントを処理したことが通知され、それ以上の処理は必要ありません。false を返すと、Android システムが onTouch イベントのハンドラーになり、ACTION_DOWN (画面に触れたときの最初のイベント) を過ぎたすべてのイベントのコードをオーバーライドします。

私も同じ問題を抱えていて、今は解決しました。私はそれがあなたを助けるかもしれないと思う..

于 2012-11-26T10:27:09.040 に答える
0

主な問題は、各ケースの最後に break ステートメントがないことです。他のケースでは失敗し、2 番目の ACTION_DOWN で false を返します。これは、ACTION_UP と MOVE が呼び出されないことを意味します。

これを修正するには: - 各ケースの最後に break ステートメントを追加します - ACTION_DOWN から常に true を返します

于 2012-11-24T08:26:45.353 に答える
0

true を返すのではなく、false を返します。

if(Math.floor(touchX/totalCellWidth) == currentX && Math.floor(touchY/totalCellHeight) == currentY) 
{
    dragging = true;
    return false;
}
于 2012-11-26T06:08:37.003 に答える
0

私はあなたTouchが毎回呼び出されていると確信しています.

クロスチェックするには、ログを印刷するだけです

@Override
public boolean onTouchEvent(MotionEvent event) 
{
   System.out.println("Touch working");
   return false;
}
于 2012-11-23T04:11:13.613 に答える