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" />
效果如图: