简体   繁体   English

Android canvas onTouch

[英]Android canvas onTouch

Right, well what I have is three classes the 'Game', 'GridView' and 'TokenView' (although only the first and final classes are all I need help with :D ) and what I am trying to do here is get which column (getY) was touched in my 'TokenView' class using an onTouch method. 是的,我所拥有的是“游戏”,“ GridView”和“ TokenView”这三个类(尽管只有第一个和最后一个类是我需要帮助的:D),我在这里想要做的是获取哪一列(getY)在我的'TokenView'类中使用了onTouch方法。

Game: 游戏:

    @Override
protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.view);

    int[][] pos = new int[mColumn][mRow];

    /*Setting ball movement frame*/
    FrameLayout tokenFrame = (FrameLayout) findViewById(R.id.widget39);
    TokenView token = new TokenView(this);
    tokenFrame.addView(token);


    /*Setting drop area*/
    FrameLayout gridFrame = (FrameLayout) findViewById(R.id.widget41);
    GridView gridArea = new GridView(this);
    gridFrame.addView(gridArea);
}
public int getPlayer(){
    return player;
}

public boolean onTouch(View v, MotionEvent event){

    if(){
        //where I need help :D
    }

    return false;
}

TokenView: 令牌视图:

public class TokenView extends View {

int Columns = 7;
public TokenView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}

protected void onDraw(Canvas canvas)
{
    super.onDraw(canvas);

    Paint col = new Paint();
    col.setColor(Color.rgb(0,103,231));
    col.setStyle(Paint.Style.FILL);

    Paint red = new Paint();
    red.setAntiAlias(true); // smoothens edge
    red.setColor(Color.RED);
    red.setStyle(Paint.Style.FILL);

    Paint yellow = new Paint();
    yellow.setAntiAlias(true); // smoothens edge
    yellow.setColor(Color.YELLOW);
    yellow.setStyle(Paint.Style.FILL);
    Rect myRect = new Rect();

    canvas.drawRect(0, 0, getWidth(), getHeight(), col);
    int columnWidth = canvas.getWidth() / 7;
    int rowHeight = (canvas.getHeight() / 17);
    int circleRadius = (canvas.getHeight() / 6) - 163;

    Game game = new Game();
    int player = game.getPlayer();


    for(int column = 0; column < Columns; column++)
    {
        if(player == 1){
            canvas.drawCircle((columnWidth*column)+55, (rowHeight)+10, circleRadius, red);
        }
        else if(player == 2){
            canvas.drawCircle((columnWidth*column)+55, (rowHeight)+10, circleRadius, yellow);
        }
        else if(player == 0){
            canvas.drawCircle((columnWidth*column)+55, (rowHeight*1)+10, circleRadius, col);
        }
    }
}

Many Thanks in advance 提前谢谢了

You should override the onTouch method in the TokenView class instead. 您应该改用TokenView类中的onTouch方法。
Canvas is just the place where things of the view are drawn. 画布只是绘制视图内容的地方。
You should write something like this in your TokenView class: 您应该在TokenView类中编写如下代码:

private Cell bufferCell;

@Override
public boolean onTouchEvent(MotionEvent event)
{
  Cell cell = getCell(event);
  if (cell != null)
  {
    switch (event.getAction())
    {
      case MotionEvent.ACTION_DOWN:
        if (cell != bufferCell)
          bufferCell = cell;

        // DO STUFF HERE.
        // THE PLAYER HAS JUST TOUCHED A CELL.
        // invalidate();
        break;
      case MotionEvent.ACTION_MOVE:
        if (cell != bufferCell)
        {
          bufferCell = cell;
          // Continue Pan
          // DO STUFF HERE
          // THE PLAYER'S FINGER IS ON A DIFFERENT CELL NOW, AND MOVING
          // invalidate();
        }
        break;
      case MotionEvent.ACTION_UP:
        // Commit Pan
        bufferCell = null;
        // DO STUFF HERE
        // THE PLAYER HAS TAKEN HIS FINGER OFF THE VIEW
        // invalidate();
        break;
    }
  }
  return true;
}

private Cell getCell(MotionEvent event)
{
  int motionX = (int) event.getX();
  int motionY = (int) event.getY();
  if (motionX > 0 && motionX < sizeOfGrid && motionY > 0
      && motionY < sizeOfGrid)
  {
    int rowIndex = motionY / currentSizeOfCell % rowCount;
    int columnIndex = motionX / currentSizeOfCell % columnCount;
    return cellArray[rowIndex][columnIndex];
  }
  return null;
}

Call invalidate() in order to redraw the view. 调用invalidate()以便重绘视图。
And don't do Game game = new Game(); 而且不要做 Game game = new Game(); inside the onDraw() method of TokenView. 在TokenView的onDraw()方法中。
It will just keep on creating new Games while you draw stuff, and you will not get any expected behavior. 它只会在您绘制内容时继续创建新的游戏,并且您不会得到任何预期的行为。

I used a bufferCell variable which will help reduce the amount of time your logic based methods will be called, because as the player moves his finger over the grid, the cell need not change. 我使用了bufferCell变量,该变量将有助于减少基于逻辑的方法被调用的时间,因为随着玩家将手指移到网格上方,单元不需要改变。 Only when it changes, calls to appropriate methods will be fired, if you follow the above mentioned code design. 如果您遵循上述代码设计,则只有在其更改时,才会触发对适当方法的调用。

Also read about as to how to create custom views in Android. 另请阅读有关如何在Android中创建自定义视图的信息。
Main methods to override are onDraw() , onSizeChanged() , and onMeasure() . 重写的主要方法是onDraw()onSizeChanged()onMeasure()

Hope that helps. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM