Paint类介绍
Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色, 样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置方法,大体上可以分为两类,一类与图形绘制相关,一类与文本绘制相关。
Canvas类介绍
当我们调整好画笔之后,现在需要绘制到画布上,这就得用Canvas类了。在android中既然把Canvas当做画布,那么就可以在画布上绘制我们想要的任何东西。除了在画布上绘制之外,还需要设置一些关于画布的属性,比如,画布的颜色、尺寸等。下面来分析Android中Canvas有哪些功能,Canvas提供了如下一些方法:
Canvas对象的获取方式有两种:一种我们通过重写View.onDraw方法,View中的Canvas对象会被当做参数传递过来,我们操作这个Canvas,效果会直接反应在View中。
(Canvas canvas) {}
另一种就是当你想创建一个Canvas对象时使用的方法:
Bitmap b = Bitmap))(Canvas canvas) {(Canvas canvas) {
(Canvas canvas) {
(Canvas canvas) {
((((float degrees, float px, float py) {
translate(px, py);
rotate(degrees);
translate(-px, -py);
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLUE);
mPaint.setColor(Color.RED);
canvas.drawRect(new Rect(0, 0, 800, 800), mPaint);
canvas.save();
mPaint.setColor(Color.YELLOW);
canvas.rotate(45);
canvas.drawRect(new Rect(0, 0, 800, 800), mPaint);
canvas.restore();
mPaint.setColor(Color.GREEN);
canvas.rotate(45,400,400);
canvas.drawRect(new Rect(0, 0, 800, 800), mPaint);
}
canvas.skew( ) - 画布的错切:
public native void skew(float sx, float sy);
这个方法只要理解了两个参数即可:
float sx:将画布在x方向上倾斜相应的角度,sx为倾斜角度的tan值;
float sy:将画布在y轴方向上倾斜相应的角度,sy为倾斜角度的tan值;
注意,这里全是倾斜角度的tan值,比如我们打算在X轴方向上倾斜45度,tan45=1;
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLUE);
mPaint.setColor(Color.RED);
canvas.drawRect(new Rect(0, 0, 400, 400), mPaint);
canvas.save();
//x方向上倾斜45度
canvas.skew(1, 0);
mPaint.setColor(Color.YELLOW);
canvas.drawRect(new Rect(0, 0, 400, 400), mPaint);
canvas.restore();
//y方向上移动400再倾斜45度
canvas.translate(0, 400);
canvas.skew(0, 1);
mPaint.setColor(Color.GREEN);
canvas.drawRect(new Rect(0, 0, 400, 400), mPaint);
}
matrix的变换应用到canvas上
@Overrideprotected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLUE);
mPaint.setColor(Color.RED);
canvas.drawRect(0, 0, 100, 100, mPaint);
canvas.save();
Matrix matrix = new Matrix();
matrix.setScale(2f, 2f);
canvas.concat(matrix);
canvas.drawRect(100, 100, 200, 200, mPaint);
canvas.restore();
canvas.drawRect(400, 400, 500, 500, mPaint);
}
Matrix延伸:
我们通过animation来实现view组件的动画效果时候,实际上是改变canvas的matrix, matrix矩阵的作用主要是对每个坐标点(x,y)转换为另外的(x’,y’),必要的时候canvas还会通过clipRect()方法改变它的绘制可见范围,这样不至于做移动的时候看不到view组件。我们看到view的动画效果时,其实它的大小和布局都没有变化,所以会看到比较搞笑的现象,就是一个button通过translate偏离原来位置后,它的touch事件响应还是在原来位置上,而不是所看到的眼前位置。
Canvas的translate(int dx, int dy)方法,其实和通过设置它的matrix的postTranslate(int dx, int dy), preTranslate(int dx, int dy)方法效果是一样的, 唯独set系列的方法和pre, post的不同,它是直接设值,而后者它们是设置matrix的增量。
更进一步,
比如preTranslate, setTranslate, postTranslate这几个方法的调用顺序对坐标变换的影响。抽象的说pre方法是向前”生长”,从队列前面加入,post方法是向后”生长”,从队列后面加入,然后从前到后按顺序执行队列即可。具体拿个例子来说,比如一个matrix调用了下列一系列的方法:
matrix.preScale(0.5f, 1); matrix.preTranslate(10, 0); matrix.postScale(0.7f, 1); matrix.postTranslate(15, 0); 则坐标变换经过的4个变换过程依次是:translate(10, 0) -> scale(0.5f, 1) -> scale(0.7f, 1) -> translate(15, 0), 所以对matrix方法的调用顺序是很重要的,不同的顺序往往会产生不同的变换效果。pre方法的调用顺序和post方法的互不影响,即以下的方法调用和前者在真实坐标变换顺序里是一致的, matrix.postScale(0.7f, 1); matrix.preScale(0.5f, 1); matrix.preTranslate(10, 0); matrix.postTranslate(15, 0);