You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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=100left=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

火山引擎 最新活动