关键点:有一点一定要提的就是,这里的hOffset是相对于path路径的水平偏移量,而vOffset也是相对于path路径的垂直偏移量,这么说可能还有点不清楚,结合下面的示例来说明,请仔细体会这里的意思:
// 1、下开口圆弧方向绘制文字 mTextPaint.setTextAlign(Paint.Align.LEFT); y += Y_SPACE; Path path = new Path(); path.addArc(new RectF(x - 150, y, x + 150, y + 300), 180,180); canvas.drawPath(path, mPointPaint); // 参考弧度线 canvas.drawTextOnPath(str, path, 0, 0, mTextPaint); // 按照path路径绘制文字,不偏移 canvas.drawTextOnPath(str, path, 30, 30, mTextPaint);// 向水平、垂直方向各偏移30 canvas.drawTextOnPath(str, path, 60, 60, mTextPaint);// 向水平、垂直方向各偏移60 // 2、上开口圆弧方向绘制文字 path.reset(); y += Y_SPACE; path.addArc(new RectF(x - 150, y, x + 150, y + 300), 0, 180); canvas.drawPath(path, mPointPaint); // 参考弧度线 canvas.drawTextOnPath(str, path, 0, 0, mTextPaint); canvas.drawTextOnPath(str, path, 30, 30, mTextPaint); canvas.drawTextOnPath(str, path, 60, 60, mTextPaint); path.close(); // 3、竖直方向绘制文字 path.reset(); path.moveTo(200, y); path.lineTo(200, y + 4 * Y_SPACE); canvas.drawPath(path, mPointPaint); // 参考弧度线 canvas.drawTextOnPath(str, path, 0, 0, mTextPaint); canvas.drawTextOnPath(str, path, 30, 60, mTextPaint); y += Y_SPACE; y += Y_SPACE; y += Y_SPACE; y += Y_SPACE; // 4、水平方向绘制文字 path.reset(); path.moveTo(x, y); path.lineTo(x + 4 * Y_SPACE, y); canvas.drawPath(path, mPointPaint); // 参考弧度线 canvas.drawTextOnPath(str, path, 0, 0, mTextPaint); canvas.drawTextOnPath(str, path, 30, 60, mTextPaint);如下是效果图,注意看图片中的红色部分,红色的线是用代码绘制出来的path参考线,红色的箭头是path的水平和垂直方向的走向,结合下图可以更好的理解drawTextOnPath的hOffset和vOffset参数。
drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)
这个方法的套路想必不用解释了。
drawTextRun()的重载方法drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, boolean isRtl, Paint paint)
drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, boolean isRtl, Paint paint)
drawTextRun()可以文字的是从左到右还是从右到左的顺序来绘制,其中倒数第二个参数isRtl就是用来控制方向的,true就是倒序绘制,false就是正序绘制,其他的参数就没啥好说的了,这个方法用法比较简单,这里就不贴代码了。另外这个方法是在API 23才开始添加的,使用时要注意。
到目前为止,Canvas的常用用法基本介绍完了,接下来就可以着重来看Paint的使用了,Paint和Canvas两者是不可分离的,两者协作,相辅相成。所以在下面的用法示例中不免要用到Canvas的相关方法。
使用Paint测量文字的尺寸,定位文字我们在开发自定义控件时,免不了要精确定位文字的文字,例如必须把文字放在某个区域的正中间,或者必须让一行文字的几何中心精确的处于某个点上,这时我们如果不懂这里的窍门可能就要盲目的试位置了,这样一点一点试出来的位置很不可靠,可能换个屏幕尺寸位置就不对了,接下来怎么来看看怎么样用最优雅的姿势来精确的定位文字。
其实在水平方向的定位还比较好说,直接使用Paint.setTextAlign()就能搞定大多需求,主要是在水平方向上稍稍复杂一点,想要定位位置,首先需要先获取文字的高度,要用到Paint的以下两个方法:
float ascent():根据文字大小获取文字顶端到文字基线的距离(返回的是负值)
float descent():根据文字大小获取文字底部到文字基线的距离(返回的事正值)
有了这两个方法那就非常好办了,首先用代码结合效果图说明一下基线、ascent、descent和文字的关系:
y += Y_SPACE; canvas.drawPoint(x, y, mPointPaint); canvas.drawLine(x - 300, y, x+300, y, mPointPaint); mTextPaint.setTextAlign(Paint.Align.CENTER);// 水平方向上让文字居中 float ascent = mTextPaint.ascent(); // 根据文字大小获取文字顶端到文字基线的距离(返回的是负值) float descent = mTextPaint.descent(); // 根据文字大小获取文字底部到文字基线的距离(返回的事正值) canvas.drawLine(x - 300, y + ascent, x+300, y + ascent, mPointPaint); canvas.drawLine(x - 300, y + descent, x+300, y + descent, mPointPaint); canvas.drawText(str, x, y, mTextPaint);效果图如下,它们直接的关系注意看图片里面的说明。