Android自定义矩形图形
我希望在我的Android用户界面中创建一个拼字板类型的视图。为此,我目前决定(仍在玩弄最好的方法)使用带有自定义BoardCell视图的TableLayout和TableRow视图作为电路板的各个单元 我对Android还是新手,以前从未创建过自定义视图。我遇到了绘制矩形的问题。我可以获得要绘制的行的第一个单元格,但无法获得要绘制的该行其余14个单元格。在调试期间,初始化所有BoardCell对象,并为每个对象调用“onDraw”。测量值和左、上、右和下位置似乎也正确。所以我的问题是。。。我做错了什么?那一定是我错过的简单的东西 我试着简单地画一些单元格的笔划(如下面的代码所示),但右边和底部的线条都不见了。我知道这与此有关,但我不明白为什么单元格的右边和底部不会被画出来 下面是所有相关代码,删除无关代码以缩短此帖子 activity_game.xmlAndroid自定义矩形图形,android,android-layout,Android,Android Layout,我希望在我的Android用户界面中创建一个拼字板类型的视图。为此,我目前决定(仍在玩弄最好的方法)使用带有自定义BoardCell视图的TableLayout和TableRow视图作为电路板的各个单元 我对Android还是新手,以前从未创建过自定义视图。我遇到了绘制矩形的问题。我可以获得要绘制的行的第一个单元格,但无法获得要绘制的该行其余14个单元格。在调试期间,初始化所有BoardCell对象,并为每个对象调用“onDraw”。测量值和左、上、右和下位置似乎也正确。所以我的问题是。。。我做
BoardCellView.java
public class BoardCellView extends View {
private static final String TAG = BoardCellView.class.getName();
private static final int STANDARD_CELL_COLOUR = Color.rgb(234, 234, 234);
private static final int DOUBLE_LETTER_CELL_COLOUR = Color.rgb(200, 175, 224);
private static final int TRIPLE_LETTER_CELL_COLOUR = Color.rgb(132, 217, 168);
private static final int DOUBLE_WORD_CELL_COLOUR = Color.rgb(255, 181, 131);
private static final int TRIPLE_WORD_CELL_COLOUR = Color.rgb(146, 205, 251);
private Paint standardCellPaint;
private Paint doubleLetterPaint;
private Paint tripleLetterPaint;
private Paint doubleWordPaint;
private Paint tripleWordPaint;
private CellType cellType;
private Rect cellRectangle;
public BoardCellView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
TypedArray typedArray = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.BoardCellView,
0, 0);
try {
this.cellType = CellType.fromInt(typedArray.getInt(R.styleable.BoardCellView_cellType, 0));
} finally {
typedArray.recycle();
}
}
/**
* Setup the paint and rectangle objects
*/
private void init() {
// The rectangle we will use to draw
this.cellRectangle = new Rect();
// Setup the Paints for each cell type
this.standardCellPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.standardCellPaint.setStyle(Paint.Style.STROKE);
this.standardCellPaint.setColor(STANDARD_CELL_COLOUR);
this.standardCellPaint.setStrokeWidth(5.0f);
this.doubleLetterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.doubleLetterPaint.setStyle(Paint.Style.FILL);
this.doubleLetterPaint.setColor(DOUBLE_LETTER_CELL_COLOUR);
this.tripleLetterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.tripleLetterPaint.setStyle(Paint.Style.FILL);
this.tripleLetterPaint.setColor(TRIPLE_LETTER_CELL_COLOUR);
this.doubleWordPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.doubleWordPaint.setStyle(Paint.Style.STROKE);
this.doubleWordPaint.setColor(DOUBLE_WORD_CELL_COLOUR);
this.doubleWordPaint.setStrokeWidth(5.0f);
this.tripleWordPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.tripleWordPaint.setStyle(Paint.Style.FILL);
this.tripleWordPaint.setColor(TRIPLE_WORD_CELL_COLOUR);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
this.cellRectangle.set(left, top, right, bottom);
Log.d(TAG, "---- " + left + ":"+ top + ":"+ right + ":"+ bottom);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Standard cell first as this is by far the most common
switch (this.cellType) {
case STANDARD:
Log.d(TAG, "---- Drawing Standard: " + this.cellRectangle.toShortString());
canvas.drawRect(this.cellRectangle, this.standardCellPaint);
break;
case DL:
Log.d(TAG, "---- Drawing DL");
canvas.drawRect(this.cellRectangle, this.doubleLetterPaint);
break;
case TL:
Log.d(TAG, "---- Drawing TL");
canvas.drawRect(this.cellRectangle, this.tripleLetterPaint);
break;
case DW:
Log.d(TAG, "---- Drawing DW: " + this.cellRectangle.toShortString());
canvas.drawRect(this.cellRectangle, this.doubleWordPaint);
break;
case TW:
Log.d(TAG, "---- Drawing TW");
canvas.drawRect(this.cellRectangle, this.tripleWordPaint);
break;
}
}
}
来自Logcat的输出(第一个是来自onLayout的输出,第二个是来自onDraw的输出)
下面是视图的绘制方式。前两行使用我的自定义视图。其余行使用具有背景色的简单视图对象
!![委员会意见]
我花了几天的时间来尝试Google和here()提供的各种解决方案,但我没有找到任何可以解决我问题的方法。提前感谢您的帮助。问题在于
onLayout()
中的cellRectangle
设置。传递到onLayout()
的矩形坐标是相对于父视图的,但是调用drawRect()
时需要在onDraw()
中使用的坐标应该是相对于视图本身的,因为Canvas
的设置使得视图的左上角对应于(0,0)
因此,父视图中的(左,上)将对应于子视图中的(0,0),并且(右,下)将对应于(右,左,下,上)。基本上,你只需要从这两者中减去(左,上)
记住这一点,将onLayout
更改如下:
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
this.cellRectangle.set(0, 0, right-left, bottom-top);
Log.d(TAG, "---- " + left + ":"+ top + ":"+ right + ":"+ bottom);
}
非常感谢。这完全有道理。我猜是因为在debug中打印出的坐标,其中父视图的坐标我假设onDraw中的画布实际上是要绘制视图的父视图的画布。我知道这一定是我的疏忽。
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
this.cellRectangle.set(0, 0, right-left, bottom-top);
Log.d(TAG, "---- " + left + ":"+ top + ":"+ right + ":"+ bottom);
}