StaticLayout高度测量不准确

7

我正在尝试使用字体Latto-Reg将多行文本绘制到位图上,但StaticLayout似乎存在问题。

paint.setTextSize(label.fontSize);
paint.setTypeface(face);
StaticLayout textLayout = new StaticLayout(label.text, paint, (int)StaticLayout.getDesiredWidth(label.text, paint), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
Bitmap bitmapAux = Bitmap.createBitmap(textLayout.getEllipsizedWidth(), textLayout.getHeight(), Bitmap.Config.ALPHA_8);
canvas.setBitmap(bitmapAux);
canvas.save();
canvas.translate(0, textLayout.height());
textLayout.draw(canvas);
canvas.restore();

根据字体和大小,纹理上下有一定的内边距,虽然文本在位图中完美地适合,但却浪费了大量的内存空间,并且使布局杂乱无章。

上/下内边距错误

我使用单行绘图进行测试,位图完美地适应了文本

paint.getTextBounds(label.text, 0, label.text.length(), rect);
Bitmap bitmapAux = Bitmap.createBitmap(rect.width(), rect.height(), Bitmap.Config.ALPHA_8);
canvas.drawText(label.text, -rect.left, -rect.bottom, paint);

完美像素

我尝试从StaticLayout获取各种指标,但它们似乎都偏离了文本:第0行边界、第0行顶部、最后一行底部...导致相同的填充问题。

编辑: 我通过使用基于偏移量的单行绘画解决了这个问题。 仍然有几种不标准的字体,StaticLayout类绘制不正确,我想知道原因。

2个回答

5
看起来Android开发者页面显示,它旨在处理多行文本和与其他Layout一起使用的情况,并且因此在文本行的顶部有空间,以便如果您将其直接放置在另一个Layout下方,则会正确地排布。实质上,它并不是为您尝试实现的目标而设计的。

总体而言,更容易从Paint.getTextBounds()获取文本范围,以了解文本在Layout内的范围。


1
我已经创建了一个最小工作示例,展示了我认为你正在尝试实现的内容:创建一个位图,其大小恰好足以容纳通过StaticLayout渲染的文本。
似乎你的代码有几个问题:
1. 在位图内部不必要地进行了垂直翻译; 2. StaticLayout没有出现height()方法。
这是我的结果:

Application result

我在位图上添加了绿色背景以说明其大小,但除此之外,我的代码与你的几乎没有差别:
public void createTexture() {
    int width = textLayout.getEllipsizedWidth();
    int height = textLayout.getHeight();
    bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas2 = new Canvas(bitmap);
    Paint p2 = new Paint();
    p2.setStyle(Style.FILL);
    p2.setColor(Color.GREEN);
    canvas2.drawRect(0, 0, width, height, p2);
    textLayout.draw(canvas2);
}

我创建了一个非常简单的自定义组件来绘制位图:

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(bitmap, 0, 0, paint);
}

看起来你可能正在尝试连续绘制多个纹理。我建议你在绘制方法中完成这一过程,先绘制一张纹理,然后在其高度上方进行垂直平移。


1
你的结果是错误的,难道你没有看到填充吗?位图必须将文本包裹在像素中。尝试使用canvas.drawtext并查看差异。 - MLProgrammer-CiM
StaticLayout似乎没有height()方法。在这里查看:http://developer.android.com/reference/android/text/Layout.html#getHeight() - MLProgrammer-CiM
请注意,在您的问题中引用了不存在的 height() 方法。 - Paul Lammertsma
1
我通过使用基于偏移量的canvas.drawText单行绘图解决了这个问题。它可以在不使用填充的情况下完成。 - MLProgrammer-CiM
顺便说一下,drawText() 产生了相同的结果。你能否在你的问题中添加一个带有边界矩形的图像来说明这个问题?我相信我漏掉了什么。 - Paul Lammertsma
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接