Android M: problem with canvas strokeWidth and strokeStyle when drawing arcs

For the following user view: If the stroke width is 0.01, then on Android M and pre-M devices (for example: candy)

enter image description here

However, if the stroke width is 0.0f, then on Android M and pre-M devices (for example: candy)

enter image description here

Are there any changes in the stroke width in Android M that should be considered? Is there a relationship between the stroke style and the stroke width?

XML Layout File:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="${relativePackage}.${activityClass}" > <com.example.testspeedtestgui.TestView android:id="@+id/testView1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentStart="true" android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" /> </RelativeLayout> 

Below is the code that implements speedometer.java:

 package com.example.testspeedtestgui; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.os.Build; import android.util.AttributeSet; import android.view.View; public class TestView extends View { private Paint outerLogoPaint; private Paint centerOuterPaint; private Path outerLogoEdge; public TestView(Context context) { super(context); init(context); } public TestView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public TestView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } private void init(Context context) { if(Build.VERSION.SDK_INT >= 11){ this.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } initDrawingTools(); } private void initDrawingTools() { float strokeWidth=0.01f; centerOuterPaint=new Paint(); centerOuterPaint.setAntiAlias(true); centerOuterPaint.setColor(Color.BLUE); centerOuterPaint.setStrokeWidth(strokeWidth); centerOuterPaint.setStrokeCap(Paint.Cap.ROUND); centerOuterPaint.setStyle(Paint.Style.STROKE); RectF rect = new RectF(); float angle = getSemicircle(0.025f,0.5f,0.975f,0.5f,rect); outerLogoEdge = new Path(); outerLogoEdge.moveTo(0.025f, 0.495f); outerLogoEdge.arcTo(rect, angle, 180); outerLogoEdge.moveTo(0.025f, 0.495f); outerLogoEdge.lineTo(0.2f, 0.495f); //Edge surrounding the lower part of outer semi circle(Logo edge Init) Logo edge Init angle = getSemicircle(0.20f,0.5f,0.80f,0.5f,rect); outerLogoEdge.arcTo(rect, angle, 180); outerLogoEdge.moveTo(0.975f, 0.495f); outerLogoEdge.lineTo(0.8f, 0.495f); } @Override protected void onDraw(Canvas canvas) { float scale = getWidth(); canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.scale(scale, scale); drawLogo(canvas); canvas.restore(); } private void drawLogo(Canvas canvas) { canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.drawPath(outerLogoEdge, centerOuterPaint); canvas.restore(); } public float getSemicircle(float xStart, float yStart, float xEnd, float yEnd, RectF ovalRectOUT) { float centerX = xStart + ((xEnd - xStart) / 2); float centerY = yStart + ((yEnd - yStart) / 2); double xLen = (xEnd - xStart); double yLen = (yEnd - yStart); float radius = (float) (Math.sqrt(xLen * xLen + yLen * yLen) / 2); RectF oval = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius); ovalRectOUT.set(oval); double radStartAngle = 0; radStartAngle = Math.atan2(yStart - centerY, xStart - centerX); float startAngle = (float) Math.toDegrees(radStartAngle); return startAngle; } } 

From the code, TestView.java seems to cause the problem centerOuterPaint.setStrokeWidth (strokeWidth).

This is part of my application module and does not work on Android M. Tested on Nexus 5 running Android 6.0.

source code https://github.com/vyshas/SpeedometerTest

+5
source share
1 answer

You have a couple of problems:

  • Never use canvas.save(Canvas.MATRIX_SAVE_FLAG); Use canvas.save() .

Note. If possible, use save-save (). It is easier and faster than individually disabling saving a matrix or clip using this method.

  1. You draw everything at the microscopic level in the range (0 ... 1). And then you increase it by almost a hundred times. This is bad. canvas.scale() should not be used this way. Instead, try drawing elements on a very ordinary scale.

    You can use canvas.getHeight() and canvas.getWidth() to get the height and width your view. Based on this detail, draw arc and line .

+1
source

All Articles