欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一个自定义控件画图形的例子让你彻底明白画布旋转和save(),restore()的使用。

程序员文章站 2022-04-13 11:53:24
...

本文通过在自定义控件上先旋转画布再画一个向上的箭头,来搞清楚画布旋转与坐标系统变换及最终展示到界面的关系。自定义控件的代码如下。

public class MyCustomView extends View {
    public MyCustomView(Context context) {
        super(context);
    }
    public MyCustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    public MyCustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    // 画箭头线的画笔
    Paint mLinePaint = new Paint();

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mLinePaint.setStrokeWidth(8);
        mLinePaint.setColor(Color.BLUE);
        int px = getWidth();
        int py = getHeight();

        // 保存画布状态
        canvas.save();

        // 以点(px / 2, py / 2)为中心顺时针旋转画布90度
        canvas.rotate(90, px / 2, py / 2);

        // 画一个向上的箭头
        canvas.drawLine(px / 2, 0, 0, py / 2, mLinePaint); // 左边的蓝色加粗斜杠
        mLinePaint.setColor(Color.RED);
        mLinePaint.setStrokeWidth(4);
        canvas.drawLine(px / 2, 0, px, py / 2, mLinePaint);// 右边的斜杠
        canvas.drawLine(px / 2, 0, px / 2, py, mLinePaint);// 垂直的竖杠

        // 画一个左上角的园
        canvas.drawCircle(50, 50, 40, mLinePaint);
        canvas.restore();

    }
}

在布局文件中展示该自定义控件。

        <com.rs.myapplication.MyCustomView
            android:layout_width="250dp"
            android:layout_height="250dp"
            android:background="#550000ff" />

展示效果如下:

一个自定义控件画图形的例子让你彻底明白画布旋转和save(),restore()的使用。

我们是画的是一个向上的箭头,并且红色圆的圆心坐标是50, 50也应该在左上角,然而箭头确是向右的,并且圆点在右上角。这是因为旋转之后画布坐标也跟着变了。
旋转之前的坐标系是这样的:
一个自定义控件画图形的例子让你彻底明白画布旋转和save(),restore()的使用。

旋转之后的坐标系就是下面这样:

一个自定义控件画图形的例子让你彻底明白画布旋转和save(),restore()的使用。

所以这时候在界面上显示的就是向右的箭头了。因为他们是画在旋转后的画布上。
我们看代码里旋转之前使用save()方法保存了画布状态,当我们调用canvas的restore()时。画布就会恢复到最后一次调用save()之前的状态。所以restore()一般和save()成对使用。我们将本例中的画圆点的时机改一下,将画布恢复到旋转之前的状态再话圆点。即把下面两句代码的顺序调换一下。

	// 调换顺序,先恢复画布,再画圆点。
   canvas.restore();
   canvas.drawCircle(50, 50, 40, mLinePaint);

这次圆点在左上角了,如下图。也就印证了画布已恢复旋转之前的状态(原点在左上角)。
一个自定义控件画图形的例子让你彻底明白画布旋转和save(),restore()的使用。

相关标签: Android开发