Question

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.

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

Was it helpful?

Solution

You should override the onTouch method in the TokenView class instead.
Canvas is just the place where things of the view are drawn.
You should write something like this in your TokenView class:

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.
And don't do Game game = new Game(); inside the onDraw() method of TokenView.
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. 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.
Main methods to override are onDraw(), onSizeChanged(), and onMeasure().

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top