Android 4.2.1 字符间距错误

10

使用CanvasdrawText()方法时,我在Android 4.2.1上看到了不同的渲染。

低于4.2版本:

输入图像描述

在Android 4.2.1(Nexus 7)上,我得到了:

输入图像描述

如您所见,文本消费非常紧密。似乎是4.2.1引入的字距问题。用于绘制文本的Paint并没有什么特别之处:

titlePaint = new Paint();
titlePaint.setAntiAlias(true);
titlePaint.setColor(0xffffffff);
titlePaint.setTextSize(0.125f);
titlePaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
titlePaint.setTextAlign(Align.CENTER);
titlePaint.setLinearText(true);
如果我不使用titlePaint.setLinearText(true)在4.2.1上会得到奇怪的结果,您可以在这里看到:Android 4.2 on Nexus 7: canvas.drawText() not working correctly 编辑:这种奇怪的行为已经报告给了Android团队:http://code.google.com/p/android/issues/detail?id=39755但它还不是一个“official”问题。
编辑(2):一些谣言声称这个问题是由于textSize < 1.0f引起的...

你的问题是什么? - THelper
为什么在Android 4.2.1上文本以那种方式呈现?我该怎么做才能修复这种不良行为? - Seraphim's
4个回答

14

我目前正在使用的解决方法是:

scalePaint.setTextSize(1.5f);

然后,在 onDraw 方法中:

canvas.save();
canvas.scale(0.01f, 0.01f);
canvas.drawText(""+i, 0.5f*100, 0.8f*100, scalePaint);                  
canvas.restore();

如您所见,我正在重新调整文本的位置,以使其到达预期的位置。


我投票支持您的回答,因为您是第一个提出解决此难题的方法。谢谢(也请投票支持这个问题,也许会有其他人看到并帮助我们!)。 - Seraphim's
2
说实话,我不是第一个发现这个问题的人,我在其他地方找到了它,我会尽快发布链接。 由于这是Android的错误,我不确定除了愚蠢的解决方法之外是否有真正的解决方案。 - scana
我仍在等待Google的回复,您可以在此处查看:http://gc.codehum.com/p/android/issues/detail?id=39755。我认为您是StackOverflow上的第一个。如果不是,请提供您找到该解决方案的链接! :) 是的,您很诚实! - Seraphim's
最后,我接受了您的答案。没有人找到了一个最终的解决方案或官方文档来解释这种行为。我不知道这个解决方法会对性能产生什么影响,但我的很多客户都会感到高兴...无论如何,谢谢。 - Seraphim's

10

在接受唯一提出解决我特定问题的变通方法的回答后,我自己回答了我的问题。那可能是一个“不错”和“最终”的解决方案:

public static void drawTextOnCanvasWithMagnifier(Canvas canvas, String text, float x, float y, Paint paint) {
        if (android.os.Build.VERSION.SDK_INT <= 15) {
            //draw normally
            canvas.drawText(text, x, y, paint);
        }
        else {
            //workaround
            float originalTextSize = paint.getTextSize();
            final float magnifier = 1000f;
            canvas.save();
            canvas.scale(1f / magnifier, 1f / magnifier);
            paint.setTextSize(originalTextSize * magnifier);
            canvas.drawText(text, x * magnifier, y * magnifier, paint);
            canvas.restore();
            paint.setTextSize(originalTextSize);
        }
    }

1
我非常喜欢你的回答,忍不住将放大镜中的1000替换为1024(希望在深层优化中能更加优化...)。 - Couitchy

0
使用此函数可以正确地绘制具有“自动换行”、“新行断点”和“文本对齐”功能的内容 -
static void drawTextWithStaticLayout(Canvas canvas, float x, float y, String text, int wrapWidth, TextPaint paint,Layout.Alignment alignment) {
    if (android.os.Build.VERSION.SDK_INT <= 15) {
        StaticLayout sl = new StaticLayout(text,paint, wrapWidth, alignment,1.0f,0.0f,false);
        sl.draw(canvas);
    }
    else {
        float originalTextSize = paint.getTextSize();
        final float magnifier = 1000f;
        canvas.save();
            canvas.translate(x,y);
            canvas.scale(1f / magnifier, 1f / magnifier);
            paint.setTextSize(originalTextSize * magnifier);
            StaticLayout sl = new StaticLayout(text,paint, (int)magnifier*wrapWidth, alignment,1.0f,0.0f,false);
            sl.draw(canvas);
        canvas.restore();
        paint.setTextSize(originalTextSize);
    }
}

0

这是一个与Android相关的漏洞,虽然它已经被提交到漏洞跟踪器中,但您可能需要+1支持它以引起一些关注:问题39755


是的,我目前正在参与报告。Android团队已经联系了我,但它仍未被标记为“真正”的问题。他们仍在调查中...感谢您提供正确的链接到Google页面。您是否遇到同样的问题? - Seraphim's
这是我的另一个问题:https://dev59.com/qWzXa4cB1Zd3GeqPRTzH#13971632 - Seraphim's

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