Android M:绘制弧时画布strokeWidth和strokeStyle问题

Vys*_*ath 6 android android-canvas android-6.0-marshmallow

对于以下自定义视图:如果笔划宽度为0.01,那么在Android M和前M设备中(例如:棒棒糖)

在此输入图像描述

但是如果笔画宽度是0.0f那么在Android M和pre-M设备中(例如:棒棒糖)

在此输入图像描述

Android M中的笔画宽度是否有变化?笔画风格和笔画宽度之间是否有依赖关系?

XML布局文件:

<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>
Run Code Online (Sandbox Code Playgroud)

实现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;

    }


}
Run Code Online (Sandbox Code Playgroud)

从代码TestView.java,centerOuterPaint.setStrokeWidth(strokeWidth)似乎导致问题.

这是我的应用模块的一部分,在Android M上无法运行.在运行Android 6.0的Nexus 5上测试过.

源代码在https://github.com/vyshas/SpeedometerTest

Hen*_*nry 1

你这里有几个问题:

  1. 切勿使用canvas.save(Canvas.MATRIX_SAVE_FLAG);而是仅使用canvas.save().

注意:如果可能,请使用无参数 save()。与使用此方法单独禁用矩阵或剪辑的保存相比,它更简单、更快速。

  1. 您正在以微观水平绘制 (0...1) 范围内的所有内容。然后你将其放大近一百倍。这不好。canvas.scale()不应该这样使用。相反,尝试以正常比例绘制元素。

    您可以使用canvas.getHeight()canvas.getWidth()来获取您所拥有的视图的height和。width基于此细节,绘制arcline