顾名思义,画笔的作用就是用来设置我们绘制图形、文本、位图的样式和颜色等信息。
一、Paint的6个内部类
- Paint.Align:设置画笔的对齐方式
- Paint.Cap:设置画笔绘制Line和Path的起始描边样式。
- Paint.FontMetrics:文字测量
- Paint.FontMetricsInt:文字测量
- Paint.Join:
- Paint.Style:画笔的样式
1、Paint.Align 设置画笔绘制文本的对齐方式。有三种对齐方式:
- Paint.Align.CENTER:居中
- Paint.Align.LEFT :左对齐
- Paint.Align.RIGHT:右对齐
通过下面简单的代码体验下:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setTextSize(20f);
Path path = new Path();
path.moveTo(100, 50);
path.lineTo(100,150);
canvas.drawPath(path, paint);
paint.setColor(Color.GREEN);
//居中
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText("I Love Android:CENTER", 100, 50, paint);
//左对齐
paint.setTextAlign(Paint.Align.LEFT);
canvas.drawText("I Love Android:LEFT", 100, 100, paint);
//右对齐
paint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText("I Love Android:RIGHT", 100, 150, paint);
}
通过上面可以看到,以绘制起点作为对齐轴线进行对称。
2、Paint.Cap 设置画笔针对Line、Path起始拐点的描边样式。有三种类型:
- BUTT:默认值,绘制的描边在预设值范围内。
- ROUND:圆滑型,起始位置会以圆形超出预设值。
- SQUARE:方形,起始位置以方形超出预设值。
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
canvas.drawLine(100, 50, 100, 350,paint);
canvas.drawLine(300, 50, 300, 350,paint);
paint.setStrokeWidth(20);
paint.setColor(Color.GREEN);
paint.setStrokeCap(Paint.Cap.BUTT);
canvas.drawLine(100, 100, 300, 100, paint);
paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawLine(100, 200, 300, 200, paint);
paint.setStrokeCap(Paint.Cap.SQUARE);
canvas.drawLine(100, 300, 300, 300, paint);
}
3、Paint.Join 设置画笔针对Line、Curve和Path之间的连接样式,有三种类型:
- Paint.Join.MITER:默认值,直线的方式连接
- Paint.Join.ROUND:圆角的连接方式
- Paint.Join.BEVEL:斜线的连接方式
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
canvas.drawLine(100, 50, 100, 350,paint);
canvas.drawLine(300, 50, 300, 350,paint);
paint.setStrokeWidth(20);
paint.setColor(Color.GREEN);
Path path = new Path();
path.moveTo(100, 100);
path.lineTo(300, 100);
path.rLineTo(0,30);
canvas.save();
for(int i=0;i<3;i++){
switch (i){
case 0:
paint.setStrokeJoin(Paint.Join.MITER);
canvas.drawPath(path, paint);
break;
case 1:
canvas.translate(0, 60);
paint.setStrokeJoin(Paint.Join.ROUND);
canvas.drawPath(path, paint);
break;
case 2:
canvas.translate(0, 60);
paint.setStrokeJoin(Paint.Join.BEVEL);
canvas.drawPath(path, paint);
break;
}
}
canvas.restore();
}
4、Paint.Style设置画笔的样式,有三种类型:
- Paint.Style.STROKE:描边
- Paint.Style.FILL:填充
- Paint.Style.FILL_AND_STROKE:描边+填充
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(2);
canvas.save();
for(int i=0;i<3;i++){
switch (i){
case 0:
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(100, 100, 200, 200, paint);
break;
case 1:
canvas.translate(0, 160);
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(100, 100, 200, 200, paint);
break;
case 2:
canvas.translate(0, 160);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawRect(100, 100, 200, 200, paint);
break;
}
}
canvas.restore();
}
通过上面我们看到Fill和Fill_AND_STROKE的区别不是很明显。但是通过对属性注释的了解,如果设置Paint的属性为Fill,则会忽略Paint其它与Stroke相关的属性,比如setStrokeCap、etStrokeJoin、setStrokeWidth,这些属性都依赖于Stroke属性。
5、Paint.FontMetrics字体测量
注:本部分讲解,取自爱哥博客
/**
* Class that describes the various metrics for a font at a given text size.
* Remember, Y values increase going down, so those values will be positive,
* and values that measure distances going up will be negative. This class
* is returned by getFontMetrics().
*/
public static class FontMetrics {
/**
* The maximum distance above the baseline for the tallest glyph in
* the font at a given text size.
*/
public float top;
/**
* The recommended distance above the baseline for singled spaced text.
*/
public float ascent;
/**
* The recommended distance below the baseline for singled spaced text.
*/
public float descent;
/**
* The maximum distance below the baseline for the lowest glyph in
* the font at a given text size.
*/
public float bottom;
/**
* The recommended additional space to add between lines of text.
*/
public float leading;
}
这张图很简单但是也很扼要的说明了top,ascent,descent,bottom,leading这五个参数。首先我们要知道Baseline基线,在Android中,文字的绘制都是从Baseline处开始的,Baseline往上至字符最高处的距离我们称之为ascent(上坡度),Baseline往下至字符最底处的距离我们称之为descent(下坡度),而leading(行间距)则表示上一行字符的descent到该行字符的ascent之间的距离,top和bottom文档描述地很模糊,其实这里我们可以借鉴一下TextView对文本的绘制,TextView在绘制文本的时候总会在文本的最外层留出一些内边距,为什么要这样做?因为TextView在绘制文本的时候考虑到了类似读音符号,可能大家很久没写过拼音了已经忘了什么叫读音符号了吧……下图中的A上面的符号就是一个拉丁文的类似读音符号的东西:
二、Paint关于常见属性设置
setColor(int color)
不做过多解释,设置画笔的颜色。
setAlpha(int a)
设置透明度,范围【0,255】,0是完全透明,255是完全不透明
setFlags(int flags)
设置画笔的属性标签,比如:ANTI_ALIAS_FLAG、DITHER_FLAG、LINEAR_TEXT_FLAG。
setAntiAlias(boolean aa)
打开抗锯齿。抗锯齿是依赖于算法的,算法决定抗锯齿的效率,在我们绘制棱角分明的图像时,比如一个矩形、一张位图,我们不需要打开抗锯齿。
setHinting(int mode)
设置画笔的
setStrokeCap(Paint.Cap cap)
设置画笔的笔头样式。
setStrokeJoin(Paint.Join join)
设置画笔的连接样式
setStrokeWidth(float width)
设置画笔描边宽度
setStyle(Paint.Style style)
设置画笔样式,FILL 、FILL_AND_STROKE 、STROKE 。
setTextAlign(Paint.Align align)
设置文字对齐方式
setTextSize(float textSize)
设置文字大小
setUnderlineText(boolean underlineText)
设置文字下划线
setXfermode(Xfermode xfermode)
设置混合模式
measureText(String text)
测量文字的宽度
setFakeBoldText(boolean fakeBoldText)
设置粗体文字,注意设置在小字体上效果会非常差 。
setDither(boolean dither)
设置清除抖动对图像的影响,会使绘制出来的图片图像更加清晰,颜色更加平滑和饱满.。
setFilterBitmap(boolean filter)
如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快速度显示。 注意:本设置项依赖于dither和xfermode的设置。
getFontMetrics()
获取当前Paint的FontMetrics对象。
setPathEffect(PathEffect effect)
设置Path的样式。
简介到此结束。