When using Canvas
and drawText()
method I see a different rendering on Android 4.2.1.
Below 4.2:
For Android 4.2.1 (Nexux 7) I get:
As you can see the text Consumption is very tight. Seems to be a kerning problem introduced in 4.2.1. The Paint used to draw text is nothing special:
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);
If I don't use titlePaint.setLinearText(true)
I get a strange result on 4.2.1 as you can see there:
Android 4.2 on Nexus 7: canvas.drawText() not working correctly
EDIT:
This strange behaviour has been reported to the Android team: http://code.google.com/p/android/issues/detail?id=39755 but it's still not a "official" issue.
EDIT (2):
Some rumors claim that the problem is a textSize < 1.0f...
Workaround, that I'm currently using:
scalePaint.setTextSize(1.5f);
then, in onDraw method:
canvas.save();
canvas.scale(0.01f, 0.01f);
canvas.drawText(""+i, 0.5f*100, 0.8f*100, scalePaint);
canvas.restore();
As you can see, I'm rescaling back the position of the text, so it's where it's supposed to be.
I answer my own question after accepting the only response that proposed a workaround for my specific issue. That could be a "nice" and "definitive" solution:
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);
}
}
This is a bug in Android and while it's already submitted to the bug tracker you might want to +1 it there to get some attention: Issue 39755
Use this function to draw correctly with word wrap
, new line break
and text alignment
features -
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);
}
}