Android 4.2 on Nexus 7: canvas.drawText() not working correctly
Asked Answered
M

3

7

I'm facing a serious issue with my Application, published on Google Play and apparently working fine on all versions of Android except for > 4.0.

This is a screenshoot from my Android 4.0 HTC phone:

enter image description here

And this is what I get on Nexus 7, Android 4.2.1 (same behaviour in the emulator):

enter image description here

I see the same behaviour for each text drawn using canvas.drawText()

the Paint used to draw text is:

paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(color); //some color
paint.setTextSize(size); //some size
paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
paint.setTextAlign(Align.CENTER);

In the logCat (4.2.1 emulator) I see a lot of

12-18 20:42:21.096: W/Trace(276): Unexpected value from nativeGetEnabledTags: 0

I use these settings in the manifest:

 <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="8" />
Miscue answered 18/12, 2012 at 20:50 Comment(1)
actually text size is 0.175f and I scale the canvas using backgroundCanvas.scale(getWidth(), getWidth());Gasperoni
M
14

I answer my own question after a lot of googling...

The trick consist in the use of setLinearText(true) for the Paint object used for drawing the text. Now, everything looks great.

paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(color);
paint.setTextSize(size);
paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
paint.setTextAlign(Align.CENTER);
paint.setLinearText(true);

Here the link that saves my day:

http://gc.codehum.com/p/android/issues/detail?id=39755

I hope it can help someonelse.

The text is not rendered at the best yet:

enter image description here

Edited (14/01/2013)

I'm still facing a kering problem (only on 4.2.1). Please see my other question here:

Android 4.2.1 wrong character kerning (spacing)

Edited (05/02/2013)

I see another projects has the same problem. Look at the link below:

http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/

If you run the sample on Nexus 4.2.1 (or in the simulator Android 4.2) you get the same "strange" text...

Edited (20/02/2013)

Found a workaround that not uses setLinearText(true), look here:

Android 4.2.1 wrong character kerning (spacing)

Miscue answered 20/12, 2012 at 11:53 Comment(2)
Thank you, thank you, thank you! You saved me from insanity! It finally works with setLinearText(true). I wish they would document these API changes better for the devs. That took me 2 weeks to get working for 4.2.1. Grrr....Barsac
I'm happy I'm not alone with this issue... As you can see, the character kerning seems to be wrong (character spacing is 0). Do you have the same problem? My other question here: #13974629Gasperoni
P
1

Android 4 defaults to Hardware Acceleration On. Some of the drawing functions do not work properly with this on. Cannot remember which ones exactly but try turning Hardware Acceleration off in the manifest file and see if it makes a difference.

Of course this may not be the cause but it worth a try.

Phosphorate answered 18/12, 2012 at 21:39 Comment(4)
Thanks. Unfortunatelly the tag android:hardwareAccelerated is not recognized below Android 3.0 so I can't use it for my application (Android 2.3.3)...Gasperoni
If you compile against Android 3 or 4 you can. It will be ignored on versions that do not support it. (Change the project build target not your manifest file)Phosphorate
Ok, I used Android SDK 3.2, android:hardwareAccelerated="false" recompiled and geting the same issue.Gasperoni
I use canvas.drawTextOnPath() to draw a curved text and text not showed in android 4.0 devices, then set Hardware Acceleration to false and every things works fine, Thanks a lot @PhosphorateDiscobolus
M
1

I had a similar problem, trying to make a view with custom letter spacing so I just made this 2 methods, hope someone finds them helpful.

/**
 * Draws a text in the canvas with spacing between each letter.
 * Basically what this method does is it split's the given text into individual letters
 * and draws each letter independently using Canvas.drawText with a separation of
 * {@code spacingX} between each letter.
 * @param canvas the canvas where the text will be drawn
 * @param text the text what will be drawn
 * @param left the left position of the text
 * @param top the top position of the text
 * @param paint holds styling information for the text
 * @param spacingPx the number of pixels between each letter that will be drawn
 */
public static void drawSpacedText(Canvas canvas, String text, float left, float top, Paint paint, float spacingPx){

    float currentLeft = left;

    for (int i = 0; i < text.length(); i++) {
        String c = text.charAt(i)+"";
        canvas.drawText(c, currentLeft, top, paint);
        currentLeft += spacingPx;
        currentLeft += paint.measureText(c);
    }
}

/**
 * returns the width of a text drawn by drawSpacedText
 */
public static float getSpacedTextWidth(Paint paint, String text, float spacingX){
    return paint.measureText(text) + spacingX * ( text.length() - 1 );
}
Mikkimiko answered 9/10, 2014 at 0:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.