自定义PathEffect的笔划上限

时间:2012-08-01 01:26:55

标签: android android-canvas paint

我正在为MapView上的路由实现自定义路径效果,我想出了如何使路径的开头和结尾四舍五入的问题(如Paint.setStrokeCap(Cap.ROUND)那样)。看截图 - 黑线 - 是我想要在最后舍入的路线

以下是我实现自定义PathEffect的方法:

public RouteOverlay(Context context)
{
    mContext = context;

    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setColor(COLOR_DEFAULT);
    mPaint.setAntiAlias(true);
    mPaint.setStrokeCap(Cap.ROUND); // this one does not work...
    mPaint.setStrokeJoin(Join.ROUND);
    PathEffect e1 = new PathDashPathEffect(createRouteLineStyle(), 10, 3, PathDashPathEffect.Style.MORPH);
    PathEffect e2 = new CornerPathEffect(10);
    mPaint.setPathEffect(new ComposePathEffect(e1, e2));
}

private Path createRouteLineStyle() 
{
    Path p = new Path();
    p.moveTo(-5, ROUTE_LINE_WIDTH/2);
    p.lineTo(5,ROUTE_LINE_WIDTH/2);
    p.lineTo(5,ROUTE_LINE_WIDTH/2-currentThickness);
    p.lineTo(-5, ROUTE_LINE_WIDTH/2-currentThickness);
    p.close();
    p.moveTo(-5, -(ROUTE_LINE_WIDTH/2));
    p.lineTo(5,-(ROUTE_LINE_WIDTH/2));
    p.lineTo(5, -(ROUTE_LINE_WIDTH/2-currentThickness));
    p.lineTo(-5, -(ROUTE_LINE_WIDTH/2-currentThickness));
    return p;
}

@Override
public void draw(Canvas canvas, final MapView mapView, boolean shadow)
{
    if(shadow) return;

    if(mDrawEnabled)
    {
        synchronized(mPoints)
        {
            canvas.drawPath(mPath, mPaint);
        }
    }
}

正如您在屏幕截图中看到的那样,该行的结尾未进行舍入(以及开始......)。 setStrokeCap(Cap.ROUND)无济于事。

所以问题是 - 如何在我的自定义路径中添加圆形帽?我在考虑在路径的末尾(和开头)使用addArc()addCircle(),但这似乎不对。

我需要自定义路径效果的原因是我需要在实际道路周围绘制路线 - 因此路线内部应该是空的并且具有内部和外部笔划线。

如果有人知道如何以其他方式产生这种路径效果 - 请告诉我,因为这个解决方案有很大的缺点我必须处理..

No stroke cap

2 个答案:

答案 0 :(得分:2)

除非您遇到此处提到的问题http://code.google.com/p/android/issues/detail?id=24873,否则我认为没有任何理由不起作用。

答案 1 :(得分:2)

我设法为我的问题找到了解决方案。 所以我摆脱了我的自定义路径效果并开始使用通常的笔画(笔画帽按预期工作)。所以我基本上画了两次我的路径:首先我绘制黑色线条,之后我画出透明线以清除前一条黑线的中心。

这种方法的唯一技巧是我需要在单独的位图中绘制路径(使用临时画布),并且当路径位图准备就绪时 - 将其渲染到主画布。

@Override
public void draw(Canvas canvas, final MapView mapView, boolean shadow)
{
    //Generate new bitmap if old bitmap doesn't equal to the screen size (f.i. when screen orientation changes)
    if(pathBitmap == null || pathBitmap.isRecycled() || pathBitmap.getWidth()!=canvas.getWidth() || pathBitmap.getHeight()!=canvas.getHeight())
    {
        if(pathBitmap != null)
        {        
            pathBitmap.recycle();
        }
        pathBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888);
        tempCanvas.setBitmap(pathBitmap);
    }

    //Render routes to the temporary bitmap
    renderPathBitmap();

    //Render temporary bitmap onto main canvas
    canvas.drawBitmap(pathBitmap, 0, 0, null);
    }
}

private void renderPath(Path path, Canvas canvas)
{
    routePaint.setStrokeWidth(ROUTE_LINE_WIDTH);
    routePaint.setColor(OUTER_COLOR);
    routePaint.setXfermode(null);

    canvas.drawPath(path, routePaint); //render outer line

    routePaint.setStrokeWidth(ROUTE_LINE_WIDTH/1.7f);
    routePaint.setColor(Color.TRANSPARENT);
    routePaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));

    canvas.drawPath(path, routePaint); //render inner line
}

结果如下:

enter image description here