#前言
在前面一篇 自定义控件——Canvas 画布,我们也看到如何使用Paint。Paint也是强大的工具类,这篇就来详细介绍。
Paint的API也非常多,具体可以参考官方网址:
Paint API:https://developer.android.google.cn/reference/android/graphics/Paint.html
这里根据这些API分为4种模式:(参考 HenCoder ),主要是便于总结与记忆,不用过于纠结。自己总结一张思维导图:
Paint()
Paint(int flags) //参考 setFlags
将画笔恢复到默认设置
将src的所有属性复制过来。
设置画笔的属性
参数:flags的值有很多,就不一一介绍。
demo:
mPaint.setTextSize(20);
mPaint.setFlags(Paint.UNDERLINE_TEXT_FLAG);//设置带下划线的文本
canvas.drawText("厉害了,我的国!!!",200,200,mPaint);
和下面的效果是一样的:
mPaint.setUnderlineText(true);//设置带下划线的文本
Paint对于颜色的处理,有多种模式,相关的例子也比较多,这里单独在另一篇介绍。
点击这里:自定义view——Paint 之颜色处理
画笔填充模式
参数:
style:设置画笔的样式,有三个值:
如图所示:(注:有些可能没有效果,是因为画笔宽度太小,不明显)
设置画笔的笔触宽度
设置画笔的笔帽风格
其值有以下3种:
设置画笔的转弯处的连接风格,使用时画笔样式不能为 FILL
join的值有以下3种:
设置连接处的倾斜度,参数值必须>=0,miter 的默认值是 4。使用时画笔样式不能为 FILL
这个方法是对setStrokeJoin( )方法的补充,当join = MITER 时,设置 MITER 型拐角的延长线的最大值。
以下介绍引用这里: 这里
当线条拐角为 MITER 时,拐角处的外缘需要使用延长线来补偿。示意图如下:
而这种补偿方案会有一个问题:如果拐角的角度太小,就有可能由于出现连接点过长的情况。比如这样:
所以为了避免意料之外的过长的尖角出现,MITER型连接点有一个额外的规则:当尖角过长时,自动改用 BEVEL的方式来渲染连接点。例如上图的这个尖角,在默认情况下是不会出现的,而是会由于延长线过长而被转为 BEVEL 型连接点:
至于多尖的角属于过于尖,尖到需要转为使用BEVEL来绘制,则是由一个属性控制的,而这个属性就是 setStrokeMiter(miter) 方法中的 miter 参数。miter 参数是对于转角长度的限制,具体来讲,是指尖角的外缘端点和内部拐角的距离与线条宽度的比。也就是下面这两个长度的比:
用几何知识得出这个比值的计算公式:如果拐角的大小为 θ ,那么这个比值就等于:
miter = 1 / sin ( θ / 2 )
在这里,miter越大,θ则越小;那么就可能会出现尖角过长的情况。miter 的默认值是 4 ,对应的是一个大约 29° 的锐角
例子:
mTestPaint.setStyle(Paint.Style.STROKE); //设置画笔风格,只描边
float miter = mPaint.getStrokeMiter();
Path path4 = new Path();
path4.moveTo(100,680);
path4.lineTo(250,680);
path4.lineTo(100,780);
path4.lineTo(100,670);
canvas.drawPath(path4, mTestPaint);
Path path5 = new Path();
mTestPaint.setStrokeMiter(100f);
path5.moveTo(500,680);
path5.lineTo(650,680);
path5.lineTo(350,740);
path5.close();//闭环
canvas.drawPath(path5, mTestPaint);
Path path6 = new Path();
mTestPaint.setStrokeMiter(2f);
path6.moveTo(200,880);
path6.lineTo(450,880);
path6.lineTo(350,980);
path6.close();//闭环
canvas.drawPath(path6, mTestPaint);
结论:设置miter,得到一个角度,大于这个角的尖角会被保留,而小于这个夹角的就会被「削成平头」
设置抗锯齿,默认没有设置
图片颜色更加平滑和饱满,图像更加清晰 ,减少视觉伪影
对于现在的配置来说,setDither(dither) 没有明细效果。默认的色彩深度已经是 32 位的 ARGB_8888
,效果已经足够清晰了。对于16 位色的 ARGB_4444 或者 RGB_565 的时候,开启它才会有比较明显的效果。
设置是否使用双线性过滤来绘制 Bitmap,貌似也没怎么用到。
在图层下方绘制阴影
构造函数:
setShadowLayer (float radius, float dx, float dy, int shadowColor)
参数:
radius:阴影半径,值越大,越模糊,等于0时,则没有阴影;
dx、dy:阴影偏移量,可为正负
shadowColor:阴影的颜色
使用:(在文本方面使用的比较多)
mPaint.reset();
mPaint.setStrokeWidth(30);
mPaint.setTextSize(80);
mPaint.setShadowLayer(10, 5, 5, Color.BLUE);
canvas.drawText("M-Ellen", 100, 300, mPaint);
需要注意的是:
1.设置阴影一般是用在绘制文本上,如果是绘制其他,需要关闭硬件加速;
2.参数shadowColor如果是带透明度的颜色值,那么阴影部分的透明度取shadowColor的值;如果shadowColor是不透明的,那么阴影部分的透明度取Paint的值,但阴影的颜色值与Paint无关。
设置发光阴影 。该方法与setShadowLayer ()类似,同样设置阴影效果,功能却强大很多,对图片的设置也非常好。
参数:
maskfilter:MaskFilter 对象,有2个子类:BlurMaskFilter, EmbossMaskFilter。
下面就介绍这2个类的使用。
BlurMaskFilter
构造函数:
BlurMaskFilter(float radius, BlurMaskFilter.Blur style)
参数:
radius:阴影模糊半径,同上
style:模糊方式,有4种,如下:
INNER:向内部模糊,外部不绘制
OUTER:向外部模糊,内部不绘制(内部为空心)
NORMAL:内部、外部都模糊
SOLID:外部模糊,内部正常绘制(内部为实心)
使用:这里写一个小demo,分别再文字、图形、图片上的效果:
private void testMaskFilter(Canvas canvas){
mPaint.reset();
mPaint.setColor(Color.RED);
mPaint.setTextSize(80);
MaskFilter maskFilter = new BlurMaskFilter(50, BlurMaskFilter.Blur.INNER);
// MaskFilter maskFilter = new BlurMaskFilter(100, BlurMaskFilter.Blur.OUTER);
// MaskFilter maskFilter = new BlurMaskFilter(100, BlurMaskFilter.Blur.NORMAL);
// MaskFilter maskFilter = new BlurMaskFilter(150, BlurMaskFilter.Blur.SOLID);
// mPaint.setMaskFilter(maskFilter);
canvas.translate(0, 350);
canvas.drawCircle(300,0,150,mPaint);
canvas.translate(0, 300);
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.d),100,0, mPaint);
}
private void testMaskFilter1(Canvas canvas){
canvas.drawColor(Color.BLACK);
mTestPaint.reset();
mTestPaint.setColor(Color.RED);
mTestPaint.setTextSize(100);
mTestPaint.setFakeBoldText(true);
// canvas.drawText("原始图片", 100, 100, mTestPaint);
MaskFilter maskFilter = new BlurMaskFilter(10, BlurMaskFilter.Blur.INNER);
// MaskFilter maskFilter = new BlurMaskFilter(10, BlurMaskFilter.Blur.OUTER);
// MaskFilter maskFilter = new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL);
// MaskFilter maskFilter = new BlurMaskFilter(30, BlurMaskFilter.Blur.SOLID);
mTestPaint.setMaskFilter(maskFilter);
canvas.drawText("Blur.INNER", 100, 100, mTestPaint);
// canvas.drawText("Blur.OUTER", 100, 100, mTestPaint);
// canvas.drawText("Blur.NORMAL", 100, 100, mTestPaint);
// canvas.drawText("Blur.SOLID", 100, 100, mTestPaint);
}
注意,这里需要选择合适的模糊半径。上面例子中,由于,模糊半径过大,会导致文字消失,所以文字单独绘制。
为了使效果更明显,这里背景色为黑色,效果图如下:
看起来是不是觉的像发光效果一样?是的,在黑色背景下,类似有内部发光、外部发光,说是发光其实是相对被模糊的部分。但在白色背景就没有那么明显了。
EmbossMaskFilter
具有浮雕效果的模糊(具体也不知道是个啥)
构造函数:
EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)
官方显示:在API P 不再使用。所以这里只是显示下效果图:
设置图形线条的样式,如设置线条为虚线
该方法的介绍,具体使用在另一篇介绍哦!
Paint的API中,文本相关的是最多的了。同样,这里也单独在另外一篇详细介绍。
点击这里:自定义View——Paint 之 文本绘制
距离上一篇总结,到现在已经过去很久,唉,惭愧(假装)!
这一篇由于篇幅很多,分了很多小模块单独介绍,后面会努力将这些小模块补上的。
嗯,会的!