前言
Paint 可以决定你所画的几何图形、文本、位图的样式和颜色变化。
mPaint.measureXX
mPaint.MeasureText
方法1:
float measureText (char[] text, int index, int count)
作用:测量文字绘制时所占用的宽度。
对参数的解释:- text 待测试的字符数组
- index 从第几个index开始测量
- count 共测量多少个字符
方法2:
float measureText (CharSequence text, int start, int end)
对参数的解释:
- text 待测试字符串
- start 从start位置开始测量字符串
- end 测量到字符串的end位置,但不包括.
方法3:
float measureText (String text, int start, int end)
例子:
char[] str="学习Paint".toCharArray(); String string="学习Paint"; float v1 = mPaint.measureText(string); Log.i(TAG,"方法1="+v1);//测量"学习Paint" float v2 = mPaint.measureText(str,0,str.length-1);//只测量"学习Pain" Log.i(TAG,"方法2="+v2); float v3=mPaint.measureText(string,1,string.length());//只测量"习Paint" Log.i(TAG,"方法3="+v3);
另外:mPaint.getTextWidths(String text, float[] widths)用于获取 text 中每个字符的宽度并返回到 widths 数组中,用到了MeasureText
方法
mPaint.breakXXX
mPaint.breakText
作用:测量指定宽度的文本宽度,超过指定宽度后截断。
方法1:
breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth)
方法2:
breakText(char[] text, int index, int count, float maxWidth, float[] measuredWidth)
方法3:
breakText(CharSequence text, int start, int end, boolean measureForwards, float maxWidth, float[] measuredWidth)
- 关键参数详解:
- measureForwards:表示文字测量的方法,true 表示从左向右开始测量.
- maxWidth:指定要测量的文本的最大宽度,也是是否截断文本的界限值.
- measuredWidth:用于接受数据,并将结果赋值给 measuredWidth[0]
mPaint.setXXX
mPaint.set
为当前画笔copy一支画笔
mPaint.setAlpha
方法:
void setAlpha (int a)
为设置透明值属性,a介于[0,255]之间
mPaint.setARGB
方法:
void setARGB (int a, int r, int g, int b)
设置透明值和三基色
mPaint.setAntiAlias
方法:
void setAntiAlias (boolean aa)
设置是否开启抗锯齿
mPaint.setColor
方法:
void setColor (int color)
设置画笔的颜色
mPaint.setColorFilter
方法:
ColorFilter setColorFilter (ColorFilter filter)
设置或清除画笔的颜色过滤器,比如去掉图片的绿色
ColorFilter
有三个子类可供设置
LightingColorFilter
作用:常用于模拟灯光效果
构造方法:LightingColorFilter(int mul, int add)
对参数的解释:
mul: 色彩倍增值,16进制的色彩值0xAARRGGBB。
add: 色彩增加值,16进制的色彩值0xAARRGGBB。
计算公式:
R' = R * colorMultiply.R + colorAdd.R
G' = G * colorMultiply.G + colorAdd.G
B' = B * colorMultiply.B + colorAdd.B
由16进制的与运算我们知道,任意的 0xAARRGGBB*0xFFFFFFFF=0xAARRGGBB,而再加上0x00000000,结果仍不变。故我们知道当 mul=0xFFFFFFFF,add=0x00000000,该过滤器并不会改变原图的色调。如果我们要增加绿色的值,我们就可以修改 add 的值为 0x0000XX00(其中 xx 介于 00-FF 之间);如果我们要去掉绿色的值,我们就可以修改 mul 中 xx 的值。总之,去掉某个颜色修改 mul 值,增加某个颜色值修改 add。
例子:
LightingColorFilter filter1=new LightingColorFilter(0xFFFFFFFF,0x00000000);
LightingColorFilter filter2=new LightingColorFilter(0xFFFF00FF,0x00000000);
LightingColorFilter filter3=new LightingColorFilter(0xFFFFFFFF,0x0000FF00);
Bitmap panda= BitmapFactory.decodeResource(getResources(), R.drawable.images);
mPaint.setColorFilter(filter1);
canvas.drawBitmap(panda,20,20,mPaint);
mPaint.reset();
mPaint.setColorFilter(filter2);
canvas.drawBitmap(panda,20,25+panda.getHeight(),mPaint);
mPaint.reset();
mPaint.setColorFilter(filter3);
canvas.drawBitmap(panda,20,30+panda.getHeight()*2,mPaint);
- ColorMatrixColorFilter
作用:通过 4*5 颜色矩阵来改善中像素的饱满度
构造方法1:
ColorMatrixColorFilter(ColorMatrix matrix)
ColorMatrix 可改变 bitmap 上的颜色和透明度(变换 RGBA 的值,达到改变的目的),可以以一组 4*5 的数组构建该对象
构造方法2:
ColorMatrixColorFilter (float[] array)
假设颜色矩阵为
[ a, b, c, d, e,
f, g, h, i, j,
k, l, m, n, o,
p, q, r, s, t ]
则计算公式为:
R’ = a*R + b*G + c*B + d*A + e;
G’ = f*R + g*G + h*B + i*A + j;
B’ = k*R + l*G + m*B + n*A + o;
A’ = p*R + q*G + r*B + s*A + t;
由矩阵相乘的原理可知,任何一个矩阵与单位矩阵相乘仍为本身(不懂去补矩阵基础知识)。那么现在类比 LightingColorFilter 的计算公式,你是否发现了点什么?没错,颜色矩阵的前 4 列(必须按顺序)采用的值产生效果与颜色倍增一致,而最后一列与颜色增加的效果一致, 接下来我们修改颜色矩阵,使之和上图中的效果一致。
例子:
ColorMatrixColorFilter filter1 = new ColorMatrixColorFilter(new float[]{
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0
});
ColorMatrixColorFilter filter2 = new ColorMatrixColorFilter(new float[]{
1, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0
});
ColorMatrixColorFilter filter3 = new ColorMatrixColorFilter(new float[]{
1, 0, 0, 0, 0,
0, 1, 0, 0, 255,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0
});
PorterDuffColorFilter
作用:通过使用单颜色或 Porter-Duff 组合模式来为源像素着色
实例:setColorFilter(Color.parseColor(“#99000000”), PorterDuff.Mode.DARKEN);
可设置ImageView的前景色为透明黑
构造方法:PorterDuffColorFilter(int color, PorterDuff.Mode mode)
对参数的解释:
- color:16 进制 ARGB 值
- mode:指定的 PorterDuff.Mode(这里主要是图像色彩混和)。共有 5 种,分别是Darken(变暗)、Lighten(变亮)、Multiply(正片叠底)、Overlay(重叠)、Screen(滤色),预知各种模式详解请耐心继续往下看。
例子:
PorterDuffColorFilter filter1=new PorterDuffColorFilter(0xFFFF0000, PorterDuff.Mode.DARKEN);
PorterDuffColorFilter filter2=new PorterDuffColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
PorterDuffColorFilter filter3=new PorterDuffColorFilter(0xFFFF0000, PorterDuff.Mode.SCREEN);
PorterDuffColorFilter filter4=new PorterDuffColorFilter(0xFFFF0000, PorterDuff.Mode.LIGHTEN);
PorterDuffColorFilter filter5=new PorterDuffColorFilter(0xFFFF0000, PorterDuff.Mode.OVERLAY);
Bitmap panda= BitmapFactory.decodeResource(getResources(), R.drawable.images);
mPaint.setColorFilter(filter1);
canvas.drawBitmap(panda,20,10,mPaint);
mPaint.setColorFilter(filter2);
canvas.drawBitmap(panda,20,15+panda.getHeight(),mPaint);
mPaint.setColorFilter(filter3);
canvas.drawBitmap(panda,20,20+panda.getHeight()*2,mPaint);
mPaint.setColorFilter(filter4);
canvas.drawBitmap(panda,20,25+panda.getHeight()*3,mPaint);
mPaint.setColorFilter(filter5);
canvas.drawBitmap(panda,20,30+panda.getHeight()*4,mPaint);
mPaint.setDither
方法:
void setDither (boolean dither)
作用:设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰。其实当下智能手机也有运动防抖功能,只要你用过一定知道区别。
mPaint.setFakeBoldText
方法:
void setFakeBoldText (boolean fakeBoldText)
设置伪粗体文本,与设置 FAKE_BOLD_TEXT_FLAG 一样,只是一种文本显示效果而已,咱不深究。
mPaint.setFilterBitmap
方法:
void setFilterBitmap (boolean filter)
设置位图进行滤波(Filter)处理
mPaint.setHinting
方法:
void setHinting (int mode)
设置字体微调, 可以是 HINTING_OFF or HINTING_ON. 由于当今手机密度高,此方法已无用武之地,略过。
mPaint.setLetterSpacing
方法:
void setLetterSpacing (float letterSpacing)
设置文本的字符间距,默认值为0,负数值会缩紧文本。注意文字本身两侧默认有间隙
mPaint.setLinearText
方法:
void setLinearText (boolean linearText)
设置文本为线性排列
mPaint.setMaskFilter
方法:
MaskFilter setMaskFilter (MaskFilter maskfilter)
设置或清除滤镜效果,传入 null 可清除之前的滤镜效果,maskfilter 由两个子类 BlurMaskFilter、EmbossMaskFilter所构造.
BlurMaskFilter 模糊滤镜
构造方法:BlurMaskFilter(float radius, BlurMaskFilter.Blur style)
对参数的解释:
- radius:设置显示的阴影半径,必须大于0
- style:待应用的阴影模式
- INNER:绘制内阴影和图片内容本身,不绘制外阴影
- NORMAL:正常阴影效果
- OUTER:不绘制内部阴影及图片内容,只绘制外阴影
- SOLID:只绘制外部阴影和图片内容,不绘制内阴影,与 INNER 相对
EmbossMaskFilter 浮雕滤镜
构造方法:EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)
对参数的解释:
- direction:指定光源的方向,由3个量构成的[x,y,z]设置
- ambient:背景光的亮度,取值区间[0,1],决定背景的明暗程度
- specular:高光系数,值越小反射越强,那么亮度也相对偏亮
- blurRadius:阴影延伸半径
例子:
mPaint.setMaskFilter(new BlurMaskFilter(5, BlurMaskFilter.Blur.NORMAL)); mPaint.setMaskFilter(new EmbossMaskFilter(new float[]{1,1,1},0.5f,8f,3f));
- BlurMaskFilter.Blur.NORMAL
- BlurMaskFilter.Blur.INNER
- BlurMaskFilter.Blur.OUTER
- BlurMaskFilter.Blur.SOLID
- 浮雕滤镜效果(可自个手动调值,感受下效果差异)
mPaint.setPathEffect
方法:
PathEffect setPathEffect (PathEffect effect)
设置或清除路径效果,传入 null清除效果
PathEffect 共有 6 个子类可用于构造对象,然后作为方法参数传入CornerPathEffect
构造方法:CornerPathEffect (float radius)
改变线段之间的圆滑度,而不是带锐角的折线形式
对参数的解释:- radius:线段之间的圆滑程度
DashPathEffect
构造方法:DashPathEffect (float[] intervals, float phase)
设置路径的虚线效果,setStroke 控制虚线的厚薄度
对参数的解释:- interval:间隔数组,控制虚线的长度,其中第一个偶数指数即 0 所对应的值(至少为 2 )表示第一条实线的长度,第一个奇数指数即 1 所对应的值表示第一条虚线的长度,第二个偶数对应实线,第二个奇数对应虚线…以此类推。数组不再由新元素,则开始从第一个数循环。
- phase: 虚实线间的间距。
此类妙用: 当虚实线的长度为整个 path 的长度时,即 intervals 数组中仅有两个相等的元素且均为 path 长度时,虚实线的间距为 0,绘制出来的效果就是一条完整的实线。而虚实线的间距如果为 0到 path 长度之间动态变化(可借助值动画动态得到【0,1】之间变化的比例),那么就会出现类似沿着路径绘制的动画效果。
DiscretePathEffect
构造方法:DiscretePathEffect (float segmentLength, float deviation)
设置离散的路径效果
对参数的解释:- segmentLength :离散片段的长度
- deviation: 随机的偏移原路径的值
PathDashPathEffect
构造方法:PathDashPathEffect (Path shape, float advance, float phase, PathDashPathEffect.Style style)
用指定的路径形状对所画的路径进行虚线化标记,与顺序有关。
对参数的理解:- shape:虚线段的路径形状
- advance:实线的间隔,即长度
- phase:虚实线间的间距
- style:由 NOMAL,ROTATE,TRANSLATES 三种样式
SumPathEffect
构造方法:SumPathEffect(PathEffect first, PathEffect second)
逐一组合路径效果,与顺序无关。
对参数的理解:- first:第一个路径效果
- second: 第二个路径效果
ComposePathEffect
构造方法:ComposePathEffect (PathEffect outerpe, PathEffect innerpe)
先指定一个内部路径效果,再指定一个外部路径效果,再将二者组合形成新的路径效果。
例子:
public class DrawPractice extends View { private Paint mPaint = new Paint(); public static final String TAG = "DrawPractice"; private PathEffect[] mPathEffects = new PathEffect[9]; private Path path; //省略构造函数 private void init() { mPaint.setColor(Color.BLUE); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); initPath(); } private void initPath() { path = new Path(); path.moveTo(20, 50);//路线起点 for (int i = 0; i <= 30; i++) {//随机生成折线 path.lineTo(i * 35, (float) (Math.random() * 100)); } mPathEffects[0]=null; mPathEffects[1]=new CornerPathEffect(5); mPathEffects[2]=new DashPathEffect(new float[]{20,10,5,1},5); mPathEffects[3]=new DiscretePathEffect(10,5); Path mPath=new Path(); mPath.addRect(0,0,10,10, Path.Direction.CCW); mPathEffects[4]=new PathDashPathEffect(mPath,20,5f,PathDashPathEffect.Style.ROTATE); //注意5,6的区别 详细看图 mPathEffects[5]=new ComposePathEffect(mPathEffects[1],mPathEffects[4]); mPathEffects[6]=new ComposePathEffect(mPathEffects[4],mPathEffects[1]); //7,8其实没区别 详细看图 mPathEffects[7]=new SumPathEffect(mPathEffects[1],mPathEffects[4]); mPathEffects[8]=new SumPathEffect(mPathEffects[4],mPathEffects[1]); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (int i = 0; i <mPathEffects.length ; i++) { mPaint.setPathEffect(mPathEffects[i]); canvas.drawPath(path,mPaint); canvas.translate(0,100); } } }
mPaint.setShader
方法:
Shader setShader (Shader shader)
设置着色器,传入null清除
对参数的解释:- shader:由 Shader 的五个子类构造传入,下面介绍。
BitmapShader
构造方法:BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)
作用:渲染位图
对参数的解释:- bitmap: 位图
- tileX:水平方向的一种模式
- tileY:竖直方向的一种模式
三种模式: - Shader.TileMode.CLAMP:重复水平或者竖直方向上位图的边缘颜色
- Shader.TileMode.MIRROR:水平或者竖直方向上重复图片的镜像,并且连接处看似无缝对接
Shader.TileMode.REPEAT:水平或者竖直方向上重复图片
例子:mPaint.setAntiAlias(true); Bitmap panda = BitmapFactory.decodeResource(getResources(), R.drawable.images); mPaint.setShader(new BitmapShader(panda, Shader.TileMode.CLAMP, Shader.TileMode.REPEAT)); canvas.drawCircle(300,300,300,mPaint); mPaint.setShader(new BitmapShader(panda, Shader.TileMode.MIRROR, Shader.TileMode.REPEAT)); canvas.drawCircle(300,900,300,mPaint);
LinearGradient
作用:设置一个沿着直线的线性渐变效果
构造方法1:LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)
对参数的解释:
- x0,y0,x1,y1:渐变直线的起点和终点
- colors:用于产生渐变效果的颜色组,非空 ,至少两种颜色
- positions:可为空,控制颜色数组不均匀的渐变,取值[0..1]
- tile:仍旧有三种模式可设置见上
构造方法2:
对参数的解释:LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
- color0:渐变的起始颜色
color1:渐变的终止颜色
例子:mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(10); mPaint.setShader(new LinearGradient(0,0,500,500, new int[]{R.color.colorPrimaryDark, Color.BLUE},null,Shader.TileMode.CLAMP)); canvas.drawRect(new RectF(20,20,200,200),mPaint);
RadialGradient
作用:产生辐射状的渐变效果
构造方法1:RadialGradient (float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode)
对参数的解释:
- centerX,centerY:辐射的中心坐标
- radius:辐射半径
- colors:渐变颜色数组,至少两种颜色
- stops:可为空,控制颜色数组不均匀的渐变,取值[0..1]
构造方法2:
对参数的解释:RadialGradient (float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)
- centerColor: 辐射中心的颜色
edgeColor:辐射边缘的颜色
例子:mPaint.setAntiAlias(true); mPaint.setShader(new RadialGradient(300,300,300, Color.RED, Color.BLUE,Shader.TileMode.CLAMP)); canvas.drawCircle(200,300,200,mPaint);
SweepGradient
作用:绕中心顺时针旋转360度渐变
构造方法1:SweepGradient (float cx, float cy, int[] colors, float[] positions)
对参数的解释:
- cx,cy: 旋转中心坐标
- colors:渐变颜色数组,至少两种颜色
- positions:可为空,控制颜色数组不均匀的渐变,取值[0..1]
构造方法2:
对参数的解释:SweepGradient (float cx, float cy, int color0, int color1)
- color0: 渐变的起始颜色
color1:渐变的终止颜色
例子:mPaint.setAntiAlias(true); mPaint.setShader(new SweepGradient(300,300 ,Color.RED, Color.BLUE)); canvas.drawCircle(200,300,200,mPaint);
ComposeShader
作用:用指定的模式组合两个渐变效果
构造方法1:ComposeShader (Shader shaderA, Shader shaderB, Xfermode mode)
对参数的解释:
- shaderA,shaderB: 要组合的两个渐变 shader
- Xfermode mode:设置两张图片相交时的混合模式,与mPaint.setXfermode()一样
构造方法2:
对参数的解释:ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
PorterDuff.Mode mode:设置两张图片相交时的混合规则
例子:BitmapShader shader = new BitmapShader(BitmapFactory.decodeResource(getResources(), R.drawable.images), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); BitmapShader shader1 = new BitmapShader(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint.setShader(new ComposeShader(shader, shader1, PorterDuff.Mode.SRC_OVER)); canvas.drawCircle(50, 50, 50, mPaint);
PorterDuffXfermode(XferMode 子类)
构造方法:
PorterDuffXfermode(PorterDuff.Mode mode)
作用:指定一个 PorterDuff规则创建Xfermode实例
PorterDuff.Mode使用详解看这
mPaint.setShaderLayer
方法:
void setShadowLayer (float radius, float dx, float dy, int shadowColor)
作用:在主图层下添加阴影效果
对参数的解释:- radius:设置显示阴影的半径
- dx,dy:基准点
- shadowColor:用于生成阴影的颜色
注意点:为文字加阴影不需要关闭硬件加速,否则都需要开启,方可显示效果。
例子:
mPaint.setColor(Color.BLUE); mPaint.setTextSize(20); mPaint.setShadowLayer(50,50,50, Color.RED); canvas.drawText("看主图层下面的阴影效果",50,50,mPaint);
mPaint.setStrikeThruText
方法:
void setStrikeThruText (boolean strikeThruText)
- 作用:设置删除线,与 setFlag(STRIKE_THRU_TEXT_FLAG)同等效果
mPaint.setStrokeCap
方法:
void setStrokeCap (Paint.Cap cap)
- 作用:当画笔的样式是 Stroke 或者 StrokeAndFill,可改变画笔的笔头样式,比如圆形的笔头(Cap.ROUND)、方形的笔头(Cap.SQUARE)
- 例子:
从左到右分别为 BUTT(默认)、ROUND、SQUARE。其中后两条线前后均会超出上下的基线,并且形状各异,很像戴了个帽子(Cap)。
mPaint.setStrokeJoin
方法:
void setStrokeJoin (Paint.Join join)
作用:当画笔的样式是 Stroke 或者 StrokeAndFill,可改变画笔在转弯时候的样式,锐角、斜切、圆角处理。
- 例子:
Cap 与 Join 详解
从左到右分别是 MITER,BEVEL,ROUND;
mPaint.setStrokeMiter
方法:
void setStrokeMiter (float miter)
- 作用:当画笔的样式是 Stroke 或者 StrokeAndFill,控制斜接连接处的角度,值必须大于等于 0,即控制Paint.Join.Miter的效果
mPaint.setStrokeWidth
方法:
void setStrokeWidth (float width)
- 作用:设置画笔的粗细程度
mPaint.setStyle
方法:
void setStyle (Paint.Style style)
- 作用:控制画笔的样式模式,有仅填充(Paint.Style.Fill),描边且填充(Paint.Style.FILL_AND_STROKE),仅描边(Paint.Style.STROKE),简单地说,就是空心还是实心。
mPaint.setSubpixelText
方法:
void setSubpixelText (boolean subpixelText)
- 作用:有助于文本在LCD屏幕上的显示效果.但由于当今手机密度高,此方法已无用武之地,略过。
mPaint.setTextAlign
方法:
void setTextAlign (Paint.Align align)
作用:设置文本的对齐方式,以有文本第一个字为基准靠左(Paint.Align.LEFT),居中(Paint.Align.CENTER),以文本最后一个字为基准靠右(Paint.Align.RIGHT)。
- 例子:
mPaint.setTextLocale
方法:
void setTextLocale (Locale locale)
作用:指定字体所使用的语言,例如Local.CHINA
mPaint.setTextScaleX
方法:
void setTextScaleX (float scaleX)
- 作用:设置文本的缩放比,默认为 1.值大于 1文本变宽,值小于 1 值变窄
- 例子:
mPaint.setTextSize
方法:
void setTextSize (float textSize)
- 作用:设置文本的字体大小
mPaint.setTextSkewX
方法:
void setTextSkewX (float skewX)
- 作用:设置文本的斜切比(也叫文字的倾斜度),默认为 0,若要使用合适的倾斜文本,推荐使用 -0.25
mPaint.setTypeface
方法:
Typeface setTypeface (Typeface typeface)
- 作用:设置文本的字体,传入 null 清除字体。Typeface 包含了字体的类型,粗细,还有倾斜、颜色等。
mPaint.setUnderlineText
方法:
void setUnderlineText (boolean underlineText)
- 作用:设置下划线
getxx及其他方法
mpaint.getFontSpace
方法:
float getFontSpacing ()
作用:返回基于当前文字大小和字体所推荐的一个行间距。在绘制多行文本的时候可以通过此方法更改文字的下一基线位置,使得两行文本之间的间距达到一个合适的值。
例子:
String text = "使用 drawText() 来绘制文字"; canvas.drawText(text, 50, 100, paint); canvas.drawText(text, 50, 100 + paint.getFontSpacing(), paint);
mpaint.getFontMetric
方法1:
Paint.FontMetrics getFontMetrics ()
方法2:
float getFontMetrics (Paint.FontMetrics metrics)
- 详解:FontMetricsInt共有 5 个值,分别是 top、bottom、ascent、descent、leading
top 与 bottom 限制了文字绘制的最大和最小的范围。ascent 和 descent 限制了字形的所有顶部与底部的范围(不同的字形有高低,有的顶高一些,有的底低一些),leading 表示两行文字各自的基线之间的间距
此图来源于扔物线大佬的杰作。
由图中按顺序,分别时 top、ascent、baseline、 descent、bottom 所在的直线。
并且以 baseline 为轴,在其上的线所在位置为负数距离,在其下的线所在的位置为正数距离。
例如:fontMetric.bottom-fonMetric.top
即表示文字上下区域的一个最大高度。
另外,如果需要多次调用方法 1,那么可以选择使用方法 2 以提高性能。
注意:如果要使绘制的多个文本 baseline 对齐,可以使用int middle = (top + bottom) / 2;
计算法来控制文本同在一条基线上。
paint.getTextBound
方法1:
void getTextBounds (String text, int start, int end, Rect bounds)
方法2:
void getTextBounds (char[] text, int index, int count, Rect bounds)
- 作用:返回文字四周的显示范围
- 参数 bound 为一个矩形对象。当方法完成测量后会将值返回给该对象,进而得到一个矩形范围。如果矩形的四个坐标再加上一定偏移值则刚好可以将文字包围住。
例子:
String text = "绘制文字"; paint.setStyle(Paint.Style.FILL); int offsetX = 50, offsetY = 100; canvas.drawText(text, offsetX, offsetY, paint); Rect bounds = new Rect(); paint.getTextBounds(text, 0, text.length(), bounds); bounds.left += offsetX; bounds.top += offsetY; bounds.right += offsetX; bounds.bottom += offsetY; paint.setStyle(Paint.Style.STROKE); canvas.drawRect(bounds, paint);
注意:此方法测量出来的值会比 measureText() 更少一些,原因在于 measuresText 方法测量的是文字所占用的宽度,而者宽度还包括类文字两边默认的一个间隙。
mPaint.setXfermode
方法:
Xfermode setXfermode (Xfermode xfermode)
作用:设置图像混合模式,其实是使用 Xfermode的子类 PorterDuffXfermode,而整个子类又是由 PorterDuff.Mode来决定的。
PorterDuff.Mode的详解
- 名称由来:该种图像组合模式时由分别叫 Porter 和 Duff 两人提出的,因此为了表示对他们的敬意,便以二人的名称合体来命名这种模式。其实他们仅提出了12种Alpha合成模式,后来为了方便便将图像混合的模式也加入到该类中。
- 作用:用于图形合成时图像的饱和度、颜色值等的图像表现。
- 关键的两个图像:原图像(Source image)和目标图像(Destination image)
- 两大模式:
- 图像混合模式
- Alpha合成模式