Android自定义GameCanvas绘制矩形异常问题排查与解决
自定义View绘制矩形异常的问题排查与解决
我最近在开发一个自定义View(GameCanvas,继承自View),在XML布局中引用后遇到了奇怪的绘制问题:部分矩形能正常显示,但循环绘制的表格和某些位置的矩形却完全看不到。下面是我的代码和排查过程,以及最终的解决方案。
自定义View代码
public class GameCanvas extends View { private Canvas canvas; private Paint painter; public GameCanvas(Context ctx, AttributeSet attrs) { super(ctx, attrs); painter = new Paint(); painter.setAntiAlias(true); painter.setColor(Color.BLACK); painter.setStyle(Paint.Style.STROKE); painter.setStrokeWidth(5); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); this.canvas = canvas; // 尝试绘制3x3表格,但无法显示 int w = 50; for(int i = 0; i<3; ++i) { for(int j = 0; j<3; ++j) { int x = j*w; int y = i*w; canvas.drawRect(x,y,w,w, painter); } } // 这个矩形能正常显示 canvas.drawRect(50,50,100,100, painter); // 这个矩形无法显示 canvas.drawRect(300,450,100,100, painter); } }
XML布局代码
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/game_bottombar" android:id="@+id/game_canvas_container"> <!-- 隐藏了具体包名 --> <com.---.---.---.GameCanvas android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
前期排查
我首先确认了Canvas本身是正常工作的——修改View的背景色可以填充整个容器区域,而且canvas.drawRect(50,50,100,100, painter);这个矩形能正常显示。通过调试我还确认了Canvas的尺寸是720x952,排除了绘制内容超出画布范围的可能,但循环的表格和canvas.drawRect(300,450,100,100, painter);就是看不到。
问题根源与解决方案
折腾了半天我才发现,是自己完全搞错了Canvas.drawRect()的参数规则!这个方法的正确参数定义是:
drawRect(float left, float top, float right, float bottom, Paint paint)
其中right是矩形右下角的x坐标(相对于Canvas原点),bottom是右下角的y坐标,而不是矩形的宽和高。
举个例子:
- 我之前写的
canvas.drawRect(300,450,100,100, painter);,这里的right=100比left=300还小,根本构不成有效的矩形,自然不会显示。 - 循环里的
canvas.drawRect(x,y,w,w, painter)同样错误,right设成了w而不是x+w,导致矩形的右边界在左边界的左侧或者重合,所以看不到任何内容。
因为没找到系统自带的、符合我“左上角坐标+宽高”使用习惯的方法,我自己封装了一个简单的绘制方法:
public void DrawRectangle(int x, int y, int w, int h) { canvas.drawRect(x, y, x+w, y+h, painter); }
用这个方法就可以按照自己习惯的方式绘制矩形,所有的绘制问题都解决了。
内容的提问来源于stack exchange,提问作者Sertilou




