坐标体系
/**
* 1、坐标的平移
* 2、特性就是在修改坐标后,这个过程中是不可逆的
*/
RectF r = new RectF(0, 0, 400, 400);
canvas.drawRect(r, mPaint);
canvas.translate(100, 100);
mPaint.setColor(Color.BLUE);
RectF r2 = new RectF(-100, -100, 400, 400);
canvas.drawRect(r2, mPaint);
mPaint.setColor(Color.YELLOW);
canvas.drawRect(new RectF(0, 0, 400, 400), mPaint);
Matrix变换矩阵
Matrix matrix0 = canvas.getMatrix();
Log.i(TAG, matrix0.toString());
输出:
Matrix{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]}
调用translate和rotate方法后打印Matrix:
//默认有一个绘图坐标系
RectF r = new RectF(0, 0, 400, 400);
canvas.drawRect(r, mPaint);
Matrix matrix = canvas.getMatrix();
Log.i(TAG, matrix.toString());
canvas.translate(100, 200);
mPaint.setColor(Color.BLUE);
RectF r2 = new RectF(0, 0, 400, 400);
canvas.drawRect(r2, mPaint);
Matrix matrix1 = canvas.getMatrix();
Log.i(TAG, matrix1.toString());
canvas.rotate(30,200,200);
mPaint.setColor(Color.YELLOW);
canvas.drawRect(new RectF(0, 0, 400, 400), mPaint);
Matrix matrix2 = canvas.getMatrix();
Log.i(TAG, matrix2.toString());
显示效果如下:
输出结果如下:
Matrix{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]}
Matrix{[1.0, 0.0, 100.0][0.0, 1.0, 200.0][0.0, 0.0, 1.0]}
Matrix{[0.8660254, -0.5, 226.79492][0.5, 0.8660254, 126.79492][0.0, 0.0, 1.0]}
WatchView
public class WatchView extends View {
private static final String TAG = "WatchView";
private int mWidth;
private int mHerght;
public WatchView(Context context) {
super(context);
}
public WatchView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public WatchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getMeasuredWidth();
mHerght = getMeasuredHeight();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画外圆
Paint paintCircle = new Paint();
paintCircle.setStrokeWidth(5);
paintCircle.setAntiAlias(true);
paintCircle.setStyle(Paint.Style.STROKE);
canvas.drawCircle(mWidth / 2,
mHerght / 2, mWidth / 2, paintCircle);
//画刻度线
Paint paintDegree = new Paint();
paintCircle.setStrokeWidth(3);
for (int i = 0; i < 12; i++) {
if (i == 0 || i == 3 || i == 6 || i == 9) {
paintDegree.setStrokeWidth(5);
paintDegree.setTextSize(100);
canvas.drawLine(mWidth / 2, mHerght / 2 - mWidth / 2,
mWidth / 2, mHerght / 2 - mWidth / 2 + 60,
paintDegree);
String degree = String.valueOf(i);
canvas.drawText(degree, mWidth / 2 - paintDegree.measureText(degree) / 2,
mHerght / 2 - mWidth / 2 + 160, paintDegree);
} else {
paintDegree.setStrokeWidth(3);
paintDegree.setTextSize(50);
canvas.drawLine(mWidth / 2, mHerght / 2 - mWidth / 2,
mWidth / 2, mHerght / 2 - mWidth / 2 + 30,
paintDegree);
String degree = String.valueOf(i);
canvas.drawText(degree, mWidth / 2 - paintDegree.measureText(degree) / 2,
mHerght / 2 - mWidth / 2 + 60, paintDegree);
}
canvas.rotate(30, mWidth / 2, mHerght / 2);
}
//画指针
Paint paintHour = new Paint();
paintHour.setStrokeWidth(20);
Paint paintMinute = new Paint();
paintMinute.setStrokeWidth(10);
// Log.i(TAG, "Current SaveCount1 = " + canvas.getSaveCount());
// canvas.save();
// Log.i(TAG, "Current SaveCount2 = " + canvas.getSaveCount());
canvas.translate(mWidth/2, mHerght/2);
canvas.drawLine(0,0,100,100,paintHour);
canvas.drawLine(0,0,100,200,paintMinute);
// canvas.restore();
Log.i(TAG, "Current SaveCount3 = " + canvas.getSaveCount());
}
}
图层
状态栈
save、 restore方法来保存和还原变换操作Matrix以及Clip剪裁,也可以通过restoreToCount直接还原到对应栈的保存状态
扫描二维码关注公众号,回复:
8705018 查看本文章
Layer栈
saveLayer的时候都会新建一个透明的图层(离屏Bitmap-离屏缓冲),并且会将saveLayer之前的一些Canvas操作延续过来, 后续的绘图操作都在新建的layer上面进行,当我们调用restore 或者 restoreToCount 时 更新到对应的图层和画布上
public class MyView extends View {
private static final String TAG = "MyView";
private Paint mPaint = null;
private Bitmap mBitmap = null;
public MyView(Context context) {
this(context, null);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lsj);
init();
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void init() {
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeWidth(10);
}
@Override
protected void onDraw(Canvas canvas) {
//第1次保存,并通过canvas.getSaveCount的到当前状态栈容量
canvas.save();
Log.i(TAG, "Current SaveCount1 = " + canvas.getSaveCount());
canvas.translate(400, 400);
RectF rectF = new RectF(0, 0, 600, 600);
canvas.drawBitmap(mBitmap, null, rectF, mPaint); //2
//第2次保存,并通过canvas.getSaveCount的到当前状态栈容量
Log.i(TAG, "Current SaveCount2 = " + canvas.getSaveCount());
canvas.rotate(45);
canvas.drawBitmap(mBitmap, null, rectF, mPaint); //3
//第3次保存,并通过canvas.getSaveCount的到当前状态栈容量
canvas.save();
mPaint.setColor(Color.YELLOW);
canvas.drawRect(new RectF(0, 0, 400, 400), mPaint);
Log.i(TAG, "Current SaveCount3 = " + canvas.getSaveCount());
canvas.restoreToCount(1);
Log.i(TAG, "Current SaveCount4 = " + canvas.getSaveCount());//2
// canvas.rotate(45);
//
// canvas.drawBitmap(mBitmap, null, rectF, mPaint);
// //第4次保存,并通过canvas.getSaveCount的到当前状态栈容量
// canvas.save();
// Log.i(TAG, "Current SaveCount4 = " + canvas.getSaveCount());
// //通过canvas.restoreToCount出栈到第三层状态
// canvas.restoreToCount(1);//出栈到指定层
// Log.i(TAG, "restoreToCount--Current SaveCount = " + canvas.getSaveCount());
//
// canvas.translate(0, 200);
//
// //rectF = new RectF(0,0,600,600);
// canvas.drawBitmap(mBitmap, null, rectF, mPaint);
// //通过canvas.restoreToCount出栈到第1层(最原始的那一层)状态
// canvas.restoreToCount(3);
// Log.i(TAG, "restoreToCount--Current SaveCount = " + canvas.getSaveCount());
// canvas.drawBitmap(mBitmap, null, rectF, mPaint);
}
}