一个自定义控件画图形的例子让你彻底明白画布旋转和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" />
展示效果如下:
我们是画的是一个向上的箭头,并且红色圆的圆心坐标是50, 50也应该在左上角,然而箭头确是向右的,并且圆点在右上角。这是因为旋转之后画布坐标也跟着变了。
旋转之前的坐标系是这样的:
旋转之后的坐标系就是下面这样:
所以这时候在界面上显示的就是向右的箭头了。因为他们是画在旋转后的画布上。
我们看代码里旋转之前使用save()方法保存了画布状态,当我们调用canvas的restore()时。画布就会恢复到最后一次调用save()之前的状态。所以restore()一般和save()成对使用。我们将本例中的画圆点的时机改一下,将画布恢复到旋转之前的状态再话圆点。即把下面两句代码的顺序调换一下。
// 调换顺序,先恢复画布,再画圆点。
canvas.restore();
canvas.drawCircle(50, 50, 40, mLinePaint);
这次圆点在左上角了,如下图。也就印证了画布已恢复旋转之前的状态(原点在左上角)。
上一篇: Java Study 2019 11.4
下一篇: 红帽推出企业Linux 6.1 正式版