一、前言
在上一节《Canvas绘图基础详解》我们说到Canvas绘图有三个基本要素:Canvas、绘图坐标系以及Paint,上一节我们详细介绍了Canvas和绘图坐标系的使用。这一节我们就来详细讲讲Paint的一些使用方式。Paint就是画笔的意思,用于设置绘制风格,如:线宽(笔触粗细)、颜色、透明度和填充风格等等。
二、常用api
- setFlags(@PaintFlag int flags): 添加标识,用以实现特定的效果
- reset():重置Paint的所有属性为默认值。相当于重新new一个,不过性能当然高一些。
- set(Paint src):把 src 的所有属性全部复制过来
- setAntiAlias(boolean aa): 设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。
- setDither(boolean dither): 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
- setStyle(Paint.Style style): 设置画笔的样式,为FILL,FILL_AND_STROKE,或STROKE
- setStrokeWidth(float width): 当画笔样式为STROKE或FILL_AND_STROKE时,设置笔刷的粗细度
- setStrokeCap(Paint.Cap cap): 当画笔样式为STROKE或FILL_AND_STROKE时,设置线头的形状, 如圆形样Cap.ROUND,或方形样式Cap.SQUARE
- setStrokeJoin(Paint.Join join): 设置结合处的样子,Miter:结合处为锐角, Round:结合处为圆弧:BEVEL:结合处为直线
- setStrokeMiter(float miter):它用于设置 MITER 型拐角的延长线的最大值。
- setXfermode(Xfermode xfermode): 设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果
- setColor(int color): 设置绘制的颜色,使用颜色值来表示,该颜色值包括透明度和RGB颜色。
- setARGB(int a,int r,int g,int b): 设置绘制的颜色,a代表透明度,r,g,b代表颜色值。
- setAlpha(int a): 设置绘制图形的透明度。
- setShader(Shader shader): 设置图像效果,使用Shader可以绘制出各种渐变效果
- setColorFilter(ColorFilter colorfilter): 设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果
- setMaskFilter(MaskFilter maskfilter): 设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等
- setShadowLayer(float radius ,float dx,float dy,int color):在图形下面设置阴影层,产生阴影效果, radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
- clearShadowLayer( ):清除阴影层
- setFilterBitmap(boolean filter): 如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作, 加快显示速度,本设置项依赖于dither和xfermode的设置
-
setPathEffect(PathEffect effect) 设置绘制路径的效果,如点画线等
- setTextSize(float textSize): 设置绘制文字的字号大小
- setTypeface(Typeface typeface): 设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等
- setFakeBoldText(boolean fakeBoldText): 模拟实现粗体文字,设置在小字体上效果会非常差
- etSubpixelText(boolean subpixelText): 设置该项为true,将有助于文本在LCD屏幕上的显示效果
- setTextAlign(Paint.Align align): 设置绘制文字的对齐方向
- setUnderlineText(boolean underlineText): 设置带有下划线的文字效果
- setStrikeThruText(boolean strikeThruText): 设置带有删除线的效果
- setTextScaleX(float scaleX): 设置绘制文字x轴的缩放比例,可以实现文字的拉伸的效果
- setTextSkewX(float skewX): 设置斜体文字,skewX为倾斜弧度
-
setLetterSpacing(float letterSpacing): 设置字符间的间距
- float ascent( ):测量baseline之上至字符最高处的距离
- float descent():baseline之下至字符最低处的距离
- float getFontSpacing():获取推荐的行间距。
- getTextBounds(String text, int start, int end, Rect bounds):获取文字的显示范围。
- float measureText(String text):测量文字的宽度并返回。
- getTextWidths(String text, float[] widths):获取字符串中每个字符的宽度,并把结果填入参数 widths。
- int breakText(char[] text, int index, int count, float maxWidth, float[] measuredWidth): 在给出宽度上限的前提下测量文字的宽度。
- …
三、用例测试
绘制效果相关
setFlags(int flags)
常用的flag有如下几种:
1 | |
举个栗子:
设置抗锯齿 mPaint.setFlags(Paint.ANTI_ALIAS_FLAG) 它等价于 mPaint.setAntiAlias(true)。
设置多个flag mPaint.setFlags(Paint.ANTI_ALIAS_FLAG | Paint.UNDERLINE_TEXT_FLAG) 同时设置抗锯齿和下划线。
设置抗锯齿 setAntiAlias(boolean aa)
抗锯齿是指在图像中,物体边缘总会或多或少的呈现三角形的锯齿,而抗锯齿就是指对图像边缘进行柔化处理,使图像边缘看起来更平滑,更接近实物的物体。
- true:柔化处理
- false:不柔化处理

设置防抖动 setDither(boolean dither)
这个api现在用的不多了,因为现在的 Android 版本的绘制,默认的色彩深度已经是 32 位的 ARGB_8888 ,效果已经足够清晰了。只有当你向自建的 Bitmap 中绘制,并且选择 16 位色的 ARGB_4444 或者 RGB_565 的时候,开启它才会有比较明显的效果。
引用wiki的一张图来展示它的效果:

设置Paint的样式 setStyle(Paint.Style style)
画笔样式有三种,默认是Paint.Style.FILL模式:
- Paint.Style.FILL:填充内部(例如这种模式画一个圆圆内部颜色是被填充的)
- Paint.Style.STROKE :描边(内部不被填充,可以用来绘制圆环)
- Paint.Style.FILL_AND_STROKE :填充内部和描边(展示效果和FILL看起来是一样的)
1 | |

设置画笔的粗细 setStrokeWidth(float width)
设置线条的宽度,单位为像素,默认值是 0。
1 | |

线条宽度 0 和 1 的区别
默认情况下,线条宽度为 0,但你会发现,这个时候它依然能够画出线,线条的宽度为 1 像素。那么它和线条宽度为 1 有什么区别呢?
其实这个和「几何变换」有关:你可以为Canvas设置Matrix来实现几何变换(如放大、缩小、平移、旋转),在几何变换之后 Canvas 绘制的内容就会发生相应变化,包括线条也会加粗,例如2像素宽度的线条在 Canvas 放大2倍后会被以4像素宽度来绘制。而当线条宽度被设置为0时,它的宽度就被固定为1像素,就算Canvas通过几何变换被放大,它也依然会被以1像素宽度来绘制。0时称作「hairline mode(发际线模式)」。
设置线头的形状 setStrokeCap(Paint.Cap cap)
线头形状有三种,默认为 Paint.Cap.BUTT :
- Paint.Cap.BUTT: 平头
- Paint.Cap.ROUND: 圆头
- Paint.Cap.SQUARE: 方头
当线条的宽度是 1 像素时,这三种线头的表现是完全一致的,全是 1 个像素的点;而当线条变粗的时候,它们就会表现出不同的样子:
1 | |

图上的红色直线是额外加上便于理解的,有了红线作为辅助,可以清晰的看出线的三种线头的区别。
设置拐角的形状 setStrokeJoin(Paint.Join join)
拐角形状有三种,默认为 Paint.Join.MITER :
- Paint.Join.MITER:尖角
- Paint.Join.BEVEL:平角
- Paint.Join.ROUND:圆角
1 | |

setStrokeMiter(float miter)
这个方法是对于 setStrokeJoin() 的一个补充,它用于设置 MITER 型拐角的延长线的最大值。所谓「延长线的最大值」,是这么一回事:
当线条拐角为 MITER 时,拐角处的外缘需要使用延长线来补偿:

而这种补偿方案会有一个问题:如果拐角的角度太小,就有可能由于出现连接点过长的情况。比如这样:

所以为了避免意料之外的过长的尖角出现, MITER 型连接点有一个额外的规则:当尖角过长时,自动改用 BEVEL 的方式来渲染连接点。例如上图的这个尖角,在默认情况下是不会出现的,而是会由于延长线过长而被转为 BEVEL 型连接点:

setStrokeMiter(miter) 方法中 miter 参数是对于转角长度的限制,具体来讲,是指尖角的外缘端点和内部拐角的距离与线条宽度的比:

用几何知识很容易得出这个比值的计算公式:如果拐角的大小为 θ ,那么这个比值就等于 1/sin(θ/2) 。
这个 miter limit 的默认值是 4,对应的是一个大约 29° 的锐,默认情况下,大于这个角的尖角会被保留,而小于这个夹角的就会被「削成平头」。
1 | |

setXfermode(Xfermode xfermode)
在SDK中 Xfermode 有三个子类:AvoidXfermode, PixelXorXfermode 和PorterDuffXfermode,前两个类在API 16被遗弃了,这里不作介绍。PorterDuffXfermode 类主要用于图形合成时的图像过渡模式计算,其概念来自于1984年在ACM SIGGRAPH计算机图形学出版物上发表了”Compositing digital images(合成数字图像)”的Tomas Porter和Tom Duff,合成图像的概念极大地推动了图形图像学的发展,PorterDuffXfermode 类名就来源于这俩人的名字组合PorterDuff。而这篇论文所论述的操作,都是关于 Alpha 通道(也就是我们通俗理解的「透明度」)的计算的,后来人们就把这类计算称为Alpha 合成 ( Alpha Compositing ) 。
PorterDuffXfermode 只有这一个构造方法 PorterDuffXfermode(PorterDuff.Mode mode),里面传入了一个PorterDuff.Mode,下面是android SDK中PorterDuff的Mode枚举类型定义:
1 | |
具体来说, PorterDuff.Mode 一共有 18 个,可以分为两类:
- Alpha 合成 (Alpha Compositing)
- 混合 (Blending)
第一类,Alpha 合成,其实就是
PorterDuff这个词所指代的算法,一共描述了 12 种将两个图像共同绘制的操作(即算法)。
看下效果图(引用自Google的官方文档):
Alpha 合成:
第二类,混合,也就是
Photoshop等制图软件里都有的那些混合模式(multiply darken lighten 之类的)。这一类操作的是颜色本身而不是Alpha通道,并不属于Alpha合成,所以和Porter与Duff这两个人也没什么关系,不过为了使用的方便,它们同样也被PorterDuff.Mode里。效果图:
还有个
ADD模式不知道为什么没有加在图上,我们待会儿用代码直接演示一下。
“Xfermode” 其实就是 “Transfer mode”,用 “X” 来代替 “Trans” 是一些美国人喜欢用的简写方式。严谨地讲, Xfermode 指的是你要绘制的内容和 Canvas 的目标位置的内容应该怎样结合计算出最终的颜色。但通俗地说,其实就是要你以绘制的内容作为源图像,以 View 中已有的内容作为目标图像,选取一个 PorterDuff.Mode 作为绘制内容的颜色处理方案。就像这样:
1 | |
Xfermode 使用很简单,不过需要注意的是必须要使用离屏缓冲(Off-screen Buffer),使用离屏缓冲有两种方式:
-
Canvas.saveLayer()可以做短时的离屏缓冲。使用方法很简单,在绘制代码的前后各加一行代码,在绘制之前保存,绘制之后恢复,见上面示例代码。 -
View.setLayerType()是直接把整个View都绘制在离屏缓冲中。setLayerType(LAYER_TYPE_HARDWARE)是使用GPU来缓冲,setLayerType(LAYER_TYPE_SOFTWARE)是直接直接用一个Bitmap来缓冲.
如果没有特殊需求,一般选用第一种方法 Canvas.saveLayer() 来设置离屏缓冲,以此来获得更高的性能。
我们使用混合模式做一个简单的loading:
1 | |
效果如下:

利用 Xfermode 可以实现很多效果,例如橡皮擦效果等,看大家脑洞了。
设置基本颜色 setColor(int color)
方法名和使用方法都非常简单直接:
1 | |

设置基本颜色 setARGB(int a, int r, int g, int b)
1 | |

设置着色器 setShader(Shader shader)
除了直接设置颜色, Paint 还可以使用 Shader 。
Shader 的中文叫做「着色器」,也是用于设置绘制颜色的。「着色器」不是 Android 独有的,它是图形领域里一个通用的概念,它和直接设置颜色的区别是,着色器设置的是一个颜色方案,或者说是一套着色规则。当设置了 Shader 之后,Paint 在绘制图形和文字时就不使用 setColor/ARGB() 设置的颜色了,而是使用 Shader 的方案中的颜色。
在 Android 的绘制里使用 Shader ,并不直接用 Shader 这个类,而是用它的几个子类。具体来讲有 LinearGradient RadialGradient SweepGradient BitmapShader ComposeShader 这么几个:
线性渐变 LinearGradient
设置两个点和两种颜色,以这两个点作为端点,使用两种颜色的渐变来绘制颜色。
构造方法:
1 | |
第一种构造方法演示:
1 | |

我们用第二种构造方法做一个文字效果:
1 | |

辐射渐变 RadialGradient
辐射渐变很好理解,就是从中心向周围辐射状的渐变。
构造方法:
1 | |
示例:
1 | |

扫描渐变 SweepGradient
构造方法:
1 | |
示例:
1 | |

BitmapShader
用 Bitmap 来着色,其实也就是用 Bitmap 的像素来作为图形或文字的填充.
1 | |

组合着色器 ComposeShader
构造方法:
1 | |
shaderA 和 shaderB 参数都很简单, PorterDuff.Mode我们在上面已经讲过了,这儿不再赘述。而 BlendMode 需要在API 29 以上才能使用,这儿不做介绍,需要了解的自行查看官方文档。
注意:ComposeShader 内部想使用相同类型的着色器(比如说使用两个BitmapShader混合)需要api26以上才支持硬件加速功能,如果api26以下需要关闭硬件加速才能看到效果。使用不同的着色器不影响。
示例:
1 | |

setColorFilter(ColorFilter colorFilter)
为绘制设置颜色过滤,颜色过滤的意思就是为绘制的内容设置一个统一的过滤策略,然后 Canvas.drawXXX() 方法会对每个像素都进行过滤后再绘制出来,常用来实现图片滤镜效果。
ColorFilter 并不直接使用,需要使用它的子类。它共有4个子类:LightingColorFilter PorterDuffColorFilter,BlendModeColorFilter 和 ColorMatrixColorFilter。
LightingColorFilter
一个颜色滤镜,可以用来模拟简单的光照效果。LightingColorFilter 的构造方法是 LightingColorFilter(int mul, int add) ,参数里的 mul 和 add 都是和颜色值格式相同的 int 值,其中 mul 用来和目标像素相乘,add 用来和目标像素相加:
1 | |
基于上面的计算规则,可以知道,一个保持原样的 LightingColorFilter ,mul 为 0xffffff,add 为 0x000000(也就是0),那么对于一个像素,它的计算过程就是:
1 | |
我们知道了计算规则,那么就可以稍微修改下传入值,做出各种各样的filter:
1 | |
或者增强原来的色彩效果:
1 | |

PorterDuffColorFilter
这个 PorterDuffColorFilter 的作用是使用一个指定的颜色和一种指定的 PorterDuff.Mode 来与绘制对象进行合成。它的构造方法是 PorterDuffColorFilter(int color, PorterDuff.Mode mode) 其中的 color 参数是指定的颜色作为源(SRC), mode 参数是 PorterDuff.Mode,和上面讲的一样。
1 | |

BlendModeColorFilter
BlendModeColorFilter 和 上面的PorterDuffColorFilter使用方式几乎一样,不过BlendMode 有API >= 29 的使用限制,可以通过官方文档查询各种混合效果,这儿不做展开。
ColorMatrixColorFilter
要了解颜色的矩阵转换,首先需要大家掌握一些矩阵运算的基本知识:

再看一下颜色矩阵乘法:

该矩阵意思就是将图中颜色(RGBA)透明度变成它原来的一半,但是我们会发现,这种算法只能乘,如果我们有相加的需求,这种明显是不适用的。所以,应该在四阶色彩变换矩阵上增加一个“哑元坐标”,来实现所列的矩阵运算:

ColorMatrixColorFilter 使用一个 ColorMatrix 来对颜色进行处理。 ColorMatrix 这个类,内部是一个 4x5 的矩阵:
1 | |
由上面的矩阵计算公式可以得出,对于颜色 [R, G, B, A] ,转换算法是这样的:
1 | |
滤镜的原理在于设置的颜色过滤器——矩阵变换,知道了原理,其它应用就简单了,我们来看几个简单的滤镜效果:
- 反相效果(曝光)
常见的照相机中的曝光也就是矩阵运算中的反向,即设原先的ARGB值为100,200,250,用最大值255减去原来的值,结果为155,55,5,就是“曝光”效果。
1 | |

- 美白效果
矩阵运算解析:首先需要知道1f是图像原色,即不改变图像滤镜。若要增强颜色达到一种美白的效果,只需要将RGB值稍加增大即可。
1 | |

- 复古效果
这是美颜相机中常见的一款滤镜形式,矩阵中有特定的算法模板。
1 | |

setMaskFilter(MaskFilter filter)
上面的 setColorFilter(filter)是对每个像素的颜色进行过滤;而这里的 setMaskFilter(filter) 则是基于整个画面来进行过滤。MaskFilter 有两种: BlurMaskFilter 和 EmbossMaskFilter。
BlurMaskFilter
模糊遮罩效果的 MaskFilter ,构造方法 BlurMaskFilter(float radius, Blur style) ,radius 参数是模糊的范围,style 是模糊的类型。一共有四种:
NORMAL: 模糊内外边框SOLID: 在边界内部画实体,模糊外面INNER: 模糊内部边框,外部不变OUTER: 内部不变,模糊外部
1 | |

EmbossMaskFilter
浮雕遮罩效果的 MaskFilter。该类已被废弃,不推荐使用。构造方法 EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius) , 参数解析:
direction指定光源的位置,长度为xxx的数组标量[x,y,z]ambient环境光的因子 (0~1),越接近0,环境光越暗specular镜面反射系数 越接近0,镜面反射越强blurRadius模糊半径 值越大,模糊效果越明显
1 | |

setShadowLayer(float radius, float dx, float dy, int shadowColor)
给绘制内容下面加一层阴影效果。参数解析:
radius:阴影的模糊范围dx:阴影在x轴方向偏移量dy:阴影在y轴方向的偏移量shadowColor:阴影的颜色
1 | |

如果要清除阴影层,使用 clearShadowLayer() 。
注意:
- 在硬件加速开启的情况下,
setShadowLayer()在API28以下只支持文字的绘制,文字之外的绘制在API28以下必须关闭硬件加速才能正常绘制阴影。 - 如果
shadowColor是半透明的,阴影的透明度就使用shadowColor自己的透明度;而如果shadowColor是不透明的,阴影的透明度就使用paint的透明度。
setFilterBitmap(boolean filter)
设置是否使用双线性过滤来绘制 Bitmap 。图像在放大绘制的时候,默认使用的是最近邻插值过滤,这种算法简单,但会出现马赛克现象;而如果开启了双线性过滤,就可以让结果图像显得更加平滑。贴一张wiki的效果图:

使用很简单:
1 | |
setPathEffect(PathEffect effect)
使用 PathEffect 来给图形的轮廓设置效果。对 Canvas 所有的图形绘制有效,也就是 drawLine() drawCircle() drawPath() 这些方法。 PathEffect 有6种,单一效果的 CornerPathEffect 、DiscretePathEffect 、DashPathEffect 、PathDashPathEffect,和组合效果的 SumPathEffect 、ComposePathEffect。
注意:setPathEffect 方法AIP28以上才支持绘制线条(Canvas.drawLine() 和 Canvas.drawLines())的硬件加速。
CornerPathEffect
把所有拐角变成圆角。
1 | |

DiscretePathEffect
线条进行随机的偏离,让轮廓变得乱七八糟。具体的做法是,把绘制改为使用定长的线段来拼接,并且在拼接的时候对路径进行随机偏离。构造方法 DiscretePathEffect(float segmentLength, float deviation)。参数解析:
segmentLength:用来拼接的每个线段的长度deviation:偏离量
1 | |

DashPathEffect
使用虚线来绘制线条。构造方法 DashPathEffect(float[] intervals, float phase),参数解析:
intervals: 数组,它指定了虚线的格式:数组中元素必须为偶数(最少是 2 个),按照「画线长度、空白长度、画线长度、空白长度」……的顺序排列。phase: 虚线的偏移量。
1 | |

PathDashPathEffect
使用一个 Path 来绘制虚线。构造方法 PathDashPathEffect(Path shape, float advance, float phase, PathDashPathEffect.Style style),参数解析:
shape: 用来绘制的虚线 Path。advance: 两个相邻的 shape 段之间的起点间隔。phase: 虚线的偏移量。style: 类型为 PathDashPathEffect.Style ,是一个枚举 ,有三个值:「位移」TRANSLATE、「旋转」ROTATE、「变体」MORPH。
1 | |

SumPathEffect
将两种 PathEffect 分别对目标进行绘制。
1 | |

ComposePathEffect
先对目标 Path 使用一个 PathEffect,然后再对这个改变后的 Path 使用另一个 PathEffect。
1 | |

绘制文字相关
我们回顾下之前讲的 Canvas 绘制文字方法 drawText(String text, float x, float y, Paint paint):
text: 文字内容x: 文字从画布上开始绘制的x坐标y: Baseline所在的y坐标paint: 画笔
Baseline的概念
我们先看一行文字各区域的分布示意图:

从上图来看,Baseline不难理解,它就是E和h的下边界线。我们还可以得出一个结论:
文字的高度 = Descent + Ascent
然而,上面这个公式并不完全准确,我们再看一个图:

我们看到,如果文字的上方有一些特殊的符号,比如上图中的 ~ 或者是我们汉语拼音中的声调时,文字区域又会多出一部分 Leading 。
因此,完整的公式应该是:
文字的高度 =
Descent+Ascent+Leading
那么,为什么第一幅图中没有说明 Leading 的存在呢,原因是我们通常在绘制一行英文或者中文时,Leading 的高度为0,如下图:

所以我们在文字绘制时不需要考虑 Leading ,图中的数值都是距离 Baseline 的距离,在 Baseline 上方为负值,下方为正值。
我们知道文字是基于基线绘制的,那么如果设计稿中要求文字居中对齐(例如文字要在一个矩形框内垂直居中显示)时我们该如何确定基线的位置呢?我画了一张图帮助理解:

通过上图很容易可以理解,如果要文字在矩形框中垂直居中对齐,那么文字的中心线要和矩形的中心线对齐,我们只需要算出文字基线到中线的距离,结合已知的矩形坐标,自然而然的就能得到文字的基线坐标:
文字基线到中线的距离 =
(Descent + Ascent ) / 2 - Descent
基线y坐标 = (rect.bottom + rect.top)/2 + 文字基线到中线的距离
注意:需要设置了Paint的文字大小后,才能得到 FontMetrics 中的各项值。
Ascent 在 基线上方,得到的值为负数,所以实际获取基线基线到中线的距离的方法为:
1 | |
示例:
1 | |

setTextSize(float textSize)
设置文字大小。
1 | |

setTypeface(Typeface typeface)
设置字体。
1 | |

setFakeBoldText(boolean fakeBoldText)
是否使用伪粗体。之所以叫伪粗体( fake bold ),因为它并不是通过选用更高 weight 的字体让文字变粗,而是通过程序在运行时把文字给「描粗」了。
1 | |

setTextAlign(Paint.Align align)
设置文字的对齐方式。一共有三个值:LEFT CETNER 和 RIGHT。默认值为 LEFT。
1 | |

setUnderlineText(boolean underlineText)
设置带有下划线的文字效果。
1 | |

setStrikeThruText(boolean strikeThruText)
设置带有删除线的效果。
1 | |

setTextScaleX(float scaleX)
设置文字横向缩放。
1 | |

setTextSkewX(float skewX)
设置文字横向错切角度(倾斜度)。
1 | |

setLetterSpacing(float letterSpacing)
设置字符间距。默认值是 0。
1 | |

float getFontSpacing()
获取推荐的行间距。
即推荐的两行文字的 baseline 的距离。这个值是系统根据文字的字体和字号自动计算的。它的作用是当你要手动绘制多行文字(而不是使用 StaticLayout)的时候,可以在换行的时候给 y 坐标加上这个值来下移文字。
1 | |

FontMetircs getFontMetrics()
获取 Paint 的 FontMetrics。
FontMetrics 是个相对专业的工具类,它提供了几个文字排印方面的数值:ascent, descent, top, bottom, leading。 前面我们讲基线时讲过,如下图:
getTextBounds(String text, int start, int end, Rect bounds)
获取文字的显示范围。参数解析:
text:是要测量的文字start:文字的起始位置end:文字结束位置bounds:是存储文字显示范围的对象,方法在测算完成之后会把结果写进bounds。
1 | |

float measureText(String text)
测量文字的宽度并返回。
getTextWidths(String text, float[] widths)
获取字符串中每个字符的宽度,并把结果填入参数 widths。
int breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth)
在给出宽度上限的前提下测量文字的宽度。如果文字的宽度超出了上限,那么在临近超限的位置截断文字。参数解析:
text:要测量的文字measureForwards:文字的测量方向,true 表示由左往右测量maxWidth:给出的宽度上限measuredWidth:方法测量完成后会把截取的文字宽度(如果宽度没有超限,则为文字总宽度)赋值给 measuredWidth[0]
1 | |

总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值。



