Android user code does not work correctly in Bean 4.2 jelly

The code below is a custom view β€” it draws a circle, adds marks in accordance with the scale, and adds scale text. This was obtained from Mind The Robot as an excellent tutorial on creating an old thermometer. http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/

This code works fine on devices running before Jelly Bean 4.1.2, but it breaks down into 4.2. At 4.2, the numbers no longer stretch around the circle, but seem to spread across the screen. The code worked fine on Nexus 7 until it got update 4.2, so it can't be a device issue. I tested it on Nexus S running 4.1.2, and Nexus 4 works 4.2, it works fine on Nexus S, but not Nexus 4.

Unfortunately, as a new user, I can’t post screenshots, I’ll try to describe it: the numbers are displayed correctly for the first half of the dial, the remaining numbers are scattered across the screen.

I looked at the changelog 4.2, but I do not see anything that could lead to this. I looked for similar problems online, but it all looks like hardware acceleration - I tried various combinations of setting hardware acceleration in the manifest, but nothing affected.

I would really appreciate any contribution to what might be causing this.

import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Typeface; import android.util.AttributeSet; import android.view.View; public class AneroidView extends View { // drawing tools private RectF rimRect; private RectF faceRect; private Paint scalePaint; private RectF scaleRect; private Paint backgroundPaint; // end drawing tools private Bitmap background; // holds the cached static part private int totalNotches = 130; private int incrementPerLargeNotch = 10; private int incrementPerSmallNotch = 1; private float degreesPerNotch = 360.0f / totalNotches; private int scaleCenterValue = 1000; // the one in the top center (12 o'clock) private int scaleMinValue = 935; private int scaleMaxValue = 1065; public AneroidView(Context context) { super(context); init(context, null); } public AneroidView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public AneroidView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } private void init(Context context, AttributeSet attrs) { rimRect = new RectF(0.1f, 0.1f, 0.9f, 0.9f); float rimSize = 0.02f; faceRect = new RectF(); faceRect.set(rimRect.left + rimSize, rimRect.top + rimSize, rimRect.right - rimSize, rimRect.bottom - rimSize); scalePaint = new Paint(); scalePaint.setStyle(Paint.Style.STROKE); scalePaint.setColor(Color.rgb(49, 79, 79)); scalePaint.setStrokeWidth(0.005f); scalePaint.setAntiAlias(true); scalePaint.setTextSize(0.045f); scalePaint.setTypeface(Typeface.SANS_SERIF); scalePaint.setTextScaleX(0.8f); scalePaint.setTextAlign(Paint.Align.CENTER); // The scale rectangular is located .10 from the outer rim. float scalePosition = 0.10f; scaleRect = new RectF(); scaleRect.set(faceRect.left + scalePosition, faceRect.top + scalePosition, faceRect.right - scalePosition, faceRect.bottom - scalePosition); } private void drawScale(Canvas canvas) { // Draw a large notch every large increment, and a small // notch every small increment. canvas.drawOval(scaleRect, scalePaint); canvas.save(Canvas.MATRIX_SAVE_FLAG); for (int i = 0; i < totalNotches; ++i) { float y1 = scaleRect.top; float y2 = y1 - 0.015f; float y3 = y1 - 0.025f; int value = notchToValue(i); if (i % (incrementPerLargeNotch/incrementPerSmallNotch) == 0) { if (value >= scaleMinValue && value <= scaleMaxValue) { // draw a nick canvas.drawLine(0.5f, y1, 0.5f, y3, scalePaint); String valueString = Integer.toString(value); // Draw the text 0.15 away from y3 which is the long nick. canvas.drawText(valueString, 0.5f, y3 - 0.015f, scalePaint); } } else{ if (value >= scaleMinValue && value <= scaleMaxValue) { // draw a nick canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint); } } canvas.rotate(degreesPerNotch, 0.5f, 0.5f); } canvas.restore(); } private int notchToValue(int value) { int rawValue = ((value < totalNotches / 2) ? value : (value - totalNotches)) * incrementPerSmallNotch; int shiftedValue = rawValue + scaleCenterValue; return shiftedValue; } private void drawBackground(Canvas canvas) { if (background != null) canvas.drawBitmap(background, 0, 0, backgroundPaint); } @Override protected void onDraw(Canvas canvas) { drawBackground(canvas); float scale = (float) getWidth(); canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.scale(scale, scale); canvas.restore(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { regenerateBackground(); } private void regenerateBackground() { // free the old bitmap if (background != null) { background.recycle(); } background = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas backgroundCanvas = new Canvas(background); float scale = (float) getWidth(); backgroundCanvas.scale(scale, scale); drawScale(backgroundCanvas); } } 
+2
source share
3 answers

Add scalePaint.setLinearText(true);

It will work better, but the text spacing may look bad.

See topics below:

Android 4.2 on Nexus 7: canvas.drawText () not working properly

Android 4.2.1 incorrect character kerning (distance)

+3
source

I managed to get around the problem using scalePaint.setLinearText (true) to get around drawing text characters in one place, setting textSize> 1.0f to get around the kerning problem, and then use canvas.scale (float, float) to get the font in the right place size. It is ugly and painful, but it works for me.

+1
source

Here is another job for the kerning issue . drawTextOnPath works like this ...

Replace this:
//canvas.drawText("Smushed text.", 0.5f, 0.7F, myTextPaint);

with this:

 private Path strightPath; <br> strightPath = new Path(); <br> strightPath.moveTo(0.1f, 0.5f);<br> strightPath.lineTo(0.9f, 0.5f); <br> canvas.drawTextOnPath("This text is not smushed together.", strightPath, 0.0f, 0.2f, myTextPaint); 
+1
source

All Articles