gpt4 book ai didi

java - 在Android中绘制动态自定义 View 棋盘

转载 作者:太空宇宙 更新时间:2023-11-04 10:11:34 27 4
gpt4 key购买 nike

我想使用canvas通过覆盖方法onDraw在android studio中动态绘制一个8×8的棋盘,我几乎已经成功了,但我遇到了一个非常烦人的问题。

我已经制作了一个自定义 View ,我的目标是使父布局与其子自定义 View 的大小相匹配,这样我的棋盘就可以覆盖整个屏幕。 (在 XML 文件中,父级和子级都设置为 match_parent)

我希望棋盘也覆盖屏幕的整个高度。

检查下面的图片这是我得到的结果,注意下部区域的巨大间隙,我的目的是垂直拉伸(stretch)棋盘并使其覆盖整个屏幕以消除该间隙。

Final Result 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方法:

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

}
}

类图 block :

   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方法:

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

类 ChessBoard 方法:

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

}

请注意,上面的 onDraw 方法是在 Chess Board 类中实现的。

我确信这个问题的解决方案在于onMeasure方法,我在想如果我增加每个方 block 的高度那么棋盘会水平拉伸(stretch)并覆盖整个屏幕?谁能告诉我我做错了什么?

最佳答案

好吧,不太确定您想要通过非方形棋盘实现什么目的,这并不是它通常的表示方式。无论如何,仅查看您的代码,下面几行看起来有点可疑:

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

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

因此,您的平铺矩形似乎总是设置为相同的宽度和高度,这是这些行的宽度和高度的最小值。

关于java - 在Android中绘制动态自定义 View 棋盘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52235810/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com