Canvas为绘图提供了以下几个非常有用的方法:
- Canvas.save()
- Canvas.restore()
- Canvas.translate()
- Canvas.rotate()
Canvas.save(),字面理解为保存画布,类似于photoshop的图层,保存之后的操作类似于在新图层上作画。
Canvas.restore(),类似于图层合并的操作,作用是将save()之后绘制的图像与save()之前的图像合并。
Canvas.translate(),Canvas是基于坐标进行绘图,这一方法的作用就是将坐标原点平移,先看一下原坐标:
若我们把黄色区域看作View画布,则坐标轴如图所示,xy箭头所指方向即为坐标轴的正向,translate(float x,float y)传入的两个参数就是新的坐标原点的坐标值。
Canvas.rotate(),与translate()类似,这一方法是旋转画布,需传入旋转角度,原点坐标xy三个参数。Canvas.rotate(45,0,0)的效果如下:
使用:
新建一个类ClockView继承View,重写onDraw()方法,然后在布局文件中引用就可以了。
案例一:
public class ClockView extends View {
public ClockView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float w = getWidth();
float h = getHeight();
/*画出外部圆盘*/
Paint paintCircle=new Paint();
paintCircle.setStyle(Paint.Style.STROKE);
paintCircle.setAntiAlias(true);
paintCircle.setStrokeWidth(5);
canvas.drawCircle(w /2, h /2, w /2,paintCircle);
/* 画出表盘内刻度*/
Paint paintDegree=new Paint();
paintDegree.setStrokeWidth(3);
for (int i=0;i<12;i++){
if (i==0||i==3||i==6||i==9){
paintDegree.setStrokeWidth(8);
paintDegree.setTextSize(40);
canvas.drawLine(w/2,h/2-w/2,w/2,h/2-w/2+90,paintDegree);
String degree=String.valueOf(i);
canvas.drawText(degree,w/2-paintDegree.measureText(degree)/2,h/2-w/2+110,paintDegree);
}else{
paintDegree.setStrokeWidth(3);
paintDegree.setTextSize(25);
canvas.drawLine(w/2,h/2-w/2,w/2,h/2-w/2+60,paintDegree);
String degree=String.valueOf(i);
canvas.drawText(degree,w/2-paintDegree.measureText(degree)/2,h/2-w/2+80,paintDegree);
}
canvas.rotate(30,w/2,h/2); //旋转画布 每绘制一条线旋转一次画布,每次转30°
}
canvas.save();
/*画出时针和分针*/
Paint paintHour=new Paint();
paintHour.setStrokeWidth(20);
Paint paintMin=new Paint();
paintMin.setStrokeWidth(10);
canvas.translate(w/2,h/2); //原点移动至圆心
canvas.drawLine(0,0,100,100,paintHour);
canvas.drawLine(0,0,0,-200,paintMin);
canvas.restore();
}
}
布局文件:
<com.example.y.study.MyView
android:layout_centerInParent="true"
android:layout_width="350dp"
android:layout_height="360dp" />
效果如图:
案例二:
public class PeopleView extends View {
public PeopleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float w=getWidth();
float h=getHeight();
Paint paint=new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
canvas.drawCircle(w/2,h/4,h/8,paint);
canvas.save();
canvas.translate(w/2,3*h/8);
canvas.drawLine(0,0,0,h/4,paint);
canvas.drawLine(-w/4,h/16,w/4,h/16,paint);
canvas.restore(); //此方法需在save()之后调用,因为它是将save()之后的绘图与save()之前合并
// 如果没有save()操作,translate()和rotate()方法将基于上一次移动进行移动或旋转
canvas.translate(w/2,5*h/8);
canvas.drawLine(0,0,-h/8,h/4,paint);
canvas.drawLine(0,0,h/8,h/4,paint);
}
}
布局文件:
<com.example.y.study.PeopleView
android:layout_centerInParent="true"
android:layout_width="350dp"
android:layout_height="350dp" />
效果如图: