本帖最后由 文晶 于 2016-8-31 12:35 编辑

前段时间在做打印测试,一般打印都是发送字膜,但是非常麻烦,需要去计算字膜,然后又封装成打印机需要的格式,总之,两个字:麻烦!后来在我苦苦计算的时候,郑总看到了,然后给我说了之前的机器是如何打印的,是不需要字膜计算的,只要把打印的内容保存成bmp,然后读bmp就可以了,因为bmp就是按照像素保存的!后来参考了皮哥的j2me代码,写了android的版本,虽然有参照,但是j2me和android毕竟还是有区别,转换的过程也遇到了很多问题,其中给画布写字符串时参数不正确导致bmp文件完全看不到内容就是其中之一,现介绍drawText()函数。

一、BaseLine

在

@Override

protected void onDraw(Canvas canvas) {

canvas.drawText("AItsuki的博客", 0,0,paint);

}复制代码就像是这样,认真看actionbar的底边:

12713cad1677138c65cc7c5cec61bf1b.gif

1.png (17 KB, 下载次数: 12)

2016-8-31 12:28 上传

二、getTextBounds那怎么才能将画出来的文字贴合屏幕呢?

这就需要计算文字的最小包裹区域了,就是没有包含字间距和行间距的区域。

Paint提供了一个方法, getTextBounds()。

传入一个Rect对象可以获得文字的左上右下(相对于左上角0,0位置)和小宽度。

我们在构造中使用,然后看下log的打印。

public Test(Context context, AttributeSet attrs) {

super(context, attrs);

paint = new Paint(Paint.ANTI_ALIAS_FLAG);

paint.setColor(0xff000000);

paint.setTextSize(60);

rect = new Rect();

paint.getTextBounds("0", 0, 1, rect);

Log.e("rect", "left = " + rect.left + ", top = " + rect.top + ", right = " + rect.right + ", bottom = " + rect.bottom);

Log.e("rect", "width = " + rect.width() +", height" +rect.height());

}复制代码

12713cad1677138c65cc7c5cec61bf1b.gif

2.png (5.18 KB, 下载次数: 8)

2016-8-31 12:30 上传

1. 贴合顶部

上面也说过,drawText("AItsuki的博客~",0, 0, Paint paint)  第三个参数y=0的位置其实就是baseline,而露出的一点点其实就是rect.bottom。很容易可以得出

当baseline = rect.height - rect.bottom的时候,就可以恰好将文字显示完全。

来校验下试试,运行下面代码:

@Override

protected void onDraw(Canvas canvas) {

paint.getTextBounds("AItsuki的博客", 0, 10, rect);

canvas.drawText("AItsuki的博客", 0,rect.height() - rect.bottom ,paint);

}复制代码

12713cad1677138c65cc7c5cec61bf1b.gif

3.png (24.64 KB, 下载次数: 5)

2016-8-31 12:32 上传

2. 贴合左边

其实换成将A换成1或者其他,会发现和屏幕左边距离一小段距离,那是因为文字本身就是有边距的,可以理解为默认字间距。

如果非要去掉左边的那么一点距离,有两种方式。

1. 第一种减去左边的边距。drawText(“007的博客~”,-rect.left , baseline, Paint paint);

2. 第二种第二种:也是减去左边的边距,换种方式减而已,设置paint.textAlign为center从中间开始画

paint.setTextAlign(Paint.Align.CENTER);

drawText("007",rect.width()/2 , baseline, Paint paint)复制代码

12713cad1677138c65cc7c5cec61bf1b.gif

4.png (16.4 KB, 下载次数: 11)

2016-8-31 12:33 上传

这两种方法都有弊端,所以不推荐使用

如果是一次性画一段文字或者每次只画一个字拼起来没问题,

但是两个字两个字的画就不太好,因为每个字的宽度都不一样,会导致字和字之间的距离不一致。

3. 居中知道了贴合顶部,这个就完全没有难度了。

我将0.0的小数点居中让你们感受一下……

public Test(Context context, AttributeSet attrs) {

super(context, attrs);

paint = new Paint(Paint.ANTI_ALIAS_FLAG);

paint.setColor(0xff000000);

paint.setTextSize(60);

// ========================

rect = new Rect();

paint.getTextBounds("0", 0, 1, rect);

numberBaseline = rect.height() - rect.bottom;

int numberHeight = rect.height();

paint.getTextBounds(".",0,1,rect);

pointBaseline = rect.height() -rect.bottom;

int pointHeight = rect.height();

pointBaseline += numberHeight*0.5f - pointHeight*0.5f;

}

@Override

protected void onDraw(Canvas canvas) {

canvas.drawText("0", 0 , numberBaseline ,paint);

canvas.drawText(".", paint.measureText("0") ,pointBaseline ,paint);

canvas.drawText("0", paint.measureText("0.") , numberBaseline ,paint);

}复制代码

12713cad1677138c65cc7c5cec61bf1b.gif

5.png (10.72 KB, 下载次数: 12)

2016-8-31 12:34 上传

三、rect.width()和 paint.measureText()前者是获取最小包裹区域的宽度,后者是获取加上左右边距的宽度。

推荐使用后者,因为前者0123456789, 各个数字的宽高不一致,onMeasure的时候不好测量,会出问题。

非要用rect.width()的话要分开计算宽高,4是最宽的但是也是最矮,0是最高的但是宽度不够,所以干脆用measureText就行了。

更多推荐