学而实习之 不亦乐乎

Android Paint 类及其用法

2023-07-26 19:27:25

Android中,自定义控件是一个经常要用到的技能,也是一个难点。需要对 View 原理有一定的理解,一般对于继承 View 的自定义控件,都需要重写 onDraw() 方法,同时需要对 Paint 这个类非常熟悉才行。

一、Paint 概述

Paint 类保存了绘制几何图形、文本和位图的样式和颜色信息。可以使用 Paint 保存的样式和颜色,来绘制图形、文本和bitmap。

1、Paint 的使用

使用Paint之前需要初始化

mPaint = new Paint();

2、Paint 操作函数

// 重置Paint。
void reset();
void set(Paint src);
void setCompatibilityScaling(float factor);
void setBidiFlags(int flags);
void setFlags(int flags);
void setHinting(int mode);
// 是否抗锯齿
void setAntiAlias(boolean aa);
// 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰  
void setDither(boolean dither);
// 设置线性文本
void setLinearText(boolean linearText);
// 设置该项为true,将有助于文本在LCD屏幕上的显示效果  
void setSubpixelText(boolean subpixelText);
// 设置下划线
void setUnderlineText(boolean underlineText);
// 设置带有删除线的效果 
void setStrikeThruText(boolean strikeThruText);
// 设置伪粗体文本,设置在小字体上效果会非常差  
void setFakeBoldText(boolean fakeBoldText);
// 如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作
// 加快显示速度,本设置项依赖于dither和xfermode的设置  
void setFilterBitmap(boolean filter);
// Paint.Style.STROKE 表示当前只绘制图形的轮廓,而Paint.Style.FILL表示填充图形。  
void setStyle(Style style);
总共有三种画笔的样式
FILL:填充内容;
STROKE:描边;
FILL_AND_STROKE:填充内容并描边。
// 设置颜色值
void setColor(int color);
// 设置透明图0~255,要在setColor后面设置才生效,注意:alpha的范围是[0..255],而不是[0..1],是一个int值。
void setAlpha(int a);

// 设置RGB及透明度
void setARGB(int a, int r, int g, int b);  
// 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度  
void setStrokeWidth(float width);
void setStrokeMiter(float miter);
// 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷末端的图形样式
// 如圆形样式Cap.ROUND,或方形样式Cap.SQUARE  
void setStrokeCap(Cap cap);
通过 setStrokeCap() 来设置线帽,总共有三种线帽:
BUTT:没有线帽,默认模式
ROUND:圆形9
SQUARE:方形
// 设置绘制时各图形的结合方式,如平滑效果等  
void setStrokeJoin(Join join);
Join有三种类型:
BEVEL:直线
ROUND:圆角
MITER:锐角
// 设置图像效果,使用Shader可以绘制出各种渐变效果  
Shader setShader(Shader shader);
// 设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果 
ColorFilter setColorFilter(ColorFilter filter);
// 设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果 
Xfermode setXfermode(Xfermode xfermode);
// 设置绘制路径的效果,如点画线等 
PathEffect setPathEffect(PathEffect effect);
// 设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等  
MaskFilter setMaskFilter(MaskFilter maskfilter);
// 设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等  
Typeface setTypeface(Typeface typeface);
设置字体样式,可以是 Typeface 类中的样式:
Typeface.DEFAULT:默认正常字体样式;
Typeface.DEFAULT_BOLD:默认粗体样式;
Typeface.MONOSPACE:等宽字体;
Typeface.SANS_SERIF:非衬线字体;
Typeface.SERIF:衬线字体;
// 设置光栅化
Rasterizer setRasterizer(Rasterizer rasterizer);
// 在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
// 注意:在Android4.0以上默认开启硬件加速,有些图形的阴影无法显示。关闭View的硬件加速 view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
void setShadowLayer(float radius, float dx, float dy, int color);
// 设置文本对齐
void setTextAlign(Align align);
三种取值:
Paint.Align.LEFT:以基准点左对齐;
Paint.Align.CENTER:以基准点居中对齐;
Paint.Align.RIGHT:以基准点右对齐;
// 设置字体大小
void setTextSize(float textSize);
// 设置文本缩放倍数,1.0f为原始
void setTextScaleX(float scaleX);
// 设置斜体文字,skewX为倾斜弧度  
void setTextSkewX(float skewX);
// 获取指定字体大小的字体属性
getFontMetrics()
getFontMetrics(FontMetrics metrics)
getFontMetricsInt()
getFontMetricsInt(FontMetricsInt fmi)
FontMetrics 类有五个属性:
ascent:字符最高处到基准线的距离,负值;
descent:字符最低处到基准线的距离;
top:最高字符到基准线的距离;
bottom:最低字符到基准线的距离;
lending:上一行字符的 descent 到下一行字符的 ascent 的距离
// 测量文本宽度
measureText(String text)
measureText(String text, int start, int end)
measureText(char[] text, int index, int count)
measureText(CharSequence text, int start, int end)
// 剪切显示,大于 maxWidth 时截取指定长度显示
breakText(char[] text, int index, int count,float maxWidth, float[] measuredWidth)
breakText(CharSequence text, int start, int end, boolean measureForwards,float maxWidth, float[] measuredWidth)
breakText(String text, boolean measureForwards,float maxWidth, float[] measuredWidth)
// 获取指定范围内的字符宽度,保存到 widths 数组中
getTextWidths(String text, float[] widths)
getTextWidths(String text, int start, int end, float[] widths)
getTextWidths(char[] text, int index, int count,float[] widths)
getTextWidths(CharSequence text, int start, int end,float[] widths)
// 获取文本边界,保存到 bounds 中,可以通过这计算文本宽高
getTextBounds(String text, int start, int end, Rect bounds)
getTextBounds(char[] text, int index, int count, Rect bounds)
getFontMetrics(FontMetrics metrics)

二、实例

1、图像阴影效果 setShadowLayer() 

Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLACK);
// 设置透明度,要在setColor后面设置才生效
paint.setAlpha(80);

// 如果不关闭硬件加速,setShadowLayer 无效
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
// (阴影的半径,X轴方向上相对主体的位移,Y轴相对位移)
paint.setShadowLayer(10, 10, 10, Color.BLACK);
paint.setTextSize(30);
canvas.drawText("画一个很大的圆", 80, 50, paint);

// cx和cy为圆点的坐标
int radius = 80;
int offest = 40;
int startX = radius + offest;
int startY = radius + offest + 40;

canvas.drawCircle(startX, startY, radius, paint);

paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
paint.setShadowLayer(20, -20, 10, Color.BLACK);
canvas.drawCircle(startX + radius * 2 + offest, startY, radius, paint);