Coder992
Coder992

Reputation: 268

Drawing a dynamic custom view chess board in Android

I would like to draw an 8 by 8 chess board dynamically in android studio using the canvas and by overriding method onDraw, I almost have succeeded but I am running into a very annoying problem.

I already made a custom view, my goal is to make the parent layout match the size of it's child custom view, so my chessboard can cover the entire screen. ( in XML file both parent and child are set to match_parent)

I want the chess board to cover the full height of the screen as well.

Check the picture below here's the result I am getting, notice that huge gap in the lower area, my purpose is to stretch the chessboard vertically and make it cover the entire screen to eliminate that space.

Final Result ChessBoard

Here's what I managed to write so far but it's not doing what I want : Class ChessBoard:

   public class ChessBoard extends View {
   private static final String TAG = ChessBoard.class.getSimpleName();

   private Rect rect;
   private static final int COLS = 8;
   private static final int ROWS = 8;

   Tile tile;
   private final  Tile[][] mTiles;
   private int x0 = 0;
   private int y0 = 0;
   private static final int DEF_SQUARE_SIZE=50;
   private int squareSize=0;
   private boolean flipped = false;

    public ChessBoard(final Context context,AttributeSet attrs) {

         super(context,attrs);
        this.mTiles = new Tile[COLS][ROWS];
        buildTiles();
        rect=new Rect();
      }

onDraw method:

     protected void onDraw(final Canvas canvas) 
      {
         int width = getWidth();

         int height = getHeight();
         squareSize=Math.min(getSquareSizeWidth(width),getSquareSizeHeight(height));
         computeOrigins(width,height);

         for (int c = 0; c < COLS; c++) {
         for (int r = 0; r < ROWS; r++) {
            final int xCoord = getXCoord(c);
            final int yCoord = getYCoord(r);

            mTiles[c][r].setTileRect(rect);

            rect.left=xCoord;
            rect.top=yCoord;
            rect.right= rect.left+squareSize;  // right
            rect.bottom=rect.top + squareSize;
            mTiles[c][r].draw(canvas);

            }
             }

Class Tile :

   public final class Tile {

      private static final String TAG = Tile.class.getSimpleName();
      private final int col;
      private final int row;

      private final Paint squareColor;
      private Rect tileRect;

    public Tile(final int col, final int row) {

      this.col = col;
      this.row = row;
      this.squareColor = new Paint();

    squareColor.setColor(isDark() ? Color.BLACK : Color.WHITE);
    squareColor.setAntiAlias(true);
}

public void draw(final Canvas canvas) {
    canvas.drawRect(tileRect, squareColor);
}

public String getColumnString() {
    switch (col) {
        case 0: return "A";
        case 1: return "B";
        case 2: return "C";
        case 3: return "D";
        case 4: return "E";
        case 5: return "F";
        case 6: return "G";
        case 7: return "H";
        default: return null;
    }
}

public String getRowString() {
    // To get the actual row, add 1 since 'row' is 0 indexed.
    return String.valueOf(row + 1);
}

public void handleTouch() {
    Log.d(TAG, "handleTouch(): col: " + col);
    Log.d(TAG, "handleTouch(): row: " + row);
    }

public boolean isDark() {
    return (col + row) % 2 == 0;
    }

public boolean isTouched(final int x, final int y) {
    return tileRect.contains(x, y);
}

public void setTileRect(final Rect tileRect) {
    this.tileRect = tileRect;
}

public String toString() {
    final String column = getColumnString();
    final String row    = getRowString();
    return "<Tile " + column + row + ">";
}

}
onMeasure Mehtod:

       protected void onMeasure(int widthMeasureSpec, int  
       heightMeasureSpec)         
       {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);

    int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
    int sqSizeW = getSquareSizeWidth(width);
    int sqSizeH = getSquareSizeHeight(height);
    int sqSize = Math.min(sqSizeW, sqSizeH);

      if (height > width) {
        int p = getMaxHeightPercentage();
        height = Math.min(getHeight(sqSize), height * p / 100);
    } else {
        width = Math.min(getWidth(sqSize), width * 65 / 100);

    }
        setMeasuredDimension(width, height);
    }

Class ChessBoard methods:

         protected int getWidth(int sqSize) {
    return sqSize * 8;
}

protected int getHeight(int sqSize) {
    return sqSize * 8;
}

private int getSquareSizeWidth(final int width) {
    return (width)/ 8;
}

private int getSquareSizeHeight(final int height) {
    return (height)/8;
}

private int getXCoord(final int x) {
    return x0 + squareSize * (flipped ? 7 - x : x);
}

private int getYCoord(final int y) {
    return y0 + squareSize * (flipped ? y : 7 - y);
}

private void computeOrigins(final int width, final int height) {
   this.x0 = (width  - squareSize *8)/2 ;
    this.y0 = (height - squareSize *8)/2;
}
protected int getMaxHeightPercentage() {
    return 75;
}

}

Kindly note that the onDraw method above is implemented in the Chess Board Class.

I am sure the solution for this problem lies in the onMeasure Method, I am thinking if I increase the height of each square then the chessboard will stretch horizontally and cover the whole screen ? Can anyone please tell me what I am doing wrong ?

Upvotes: 2

Views: 4931

Answers (1)

Knight Forked
Knight Forked

Reputation: 1619

Well, not quite sure what you want to achieve by having a non-square chessboard which is not how usually it is represented. In any case, just looking at your code somehow following lines looks a bit suspicious:

squareSize=Math.min(getSquareSizeWidth(width),getSquareSizeHeight(height));

and

rect.right= rect.left+squareSize;  // right
rect.bottom=rect.top + squareSize;

So, your tile rect always seems to be setting to same width and height, which is minimum of width and height as per these lines.

Upvotes: 0

Related Questions