Custom path line style when drawing on canvas

前端 未结 2 1758
不思量自难忘°
不思量自难忘° 2021-02-02 03:01

I\'m currently working on map overlay which highlights the route along specified points and I need to implement certain line style (something like on screenshot)

相关标签:
2条回答
  • 2021-02-02 03:21

    I managed to find a better solution for my problem. So I got rid of my custom path effect and started to use usual stroke. So I basically draw my path 2 times: at first I draw black line, after that I draw thiner transparent line to clear the center of previous black line.

    The only trick in this approach is that I need to draw my path in a separate bitmap (using temp canvas) and when path bitmap is ready - render it to the main canvas.

    Hope this will help somebody else

    @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
    }
    

    So result looks like:

    enter image description here

    0 讨论(0)
  • 2021-02-02 03:29

    I get pretty good results with PathDashPathEffect using a "dash stamp" that's two very thin rectangles and the MORPH style option. See last and 3rd last line here:

    enter image description here

    This was drawn by modifying the PathEffects example in ApiDemos taken from the SDK:

    package com.example.android.apis.graphics;
    
    import android.content.Context;
    import android.graphics.*;
    import android.os.Bundle;
    import android.view.KeyEvent;
    import android.view.View;
    
    public class PathEffects extends GraphicsActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(new SampleView(this));
        }
    
        private static class SampleView extends View {
            private Paint mPaint;
            private Path mPath;
            private PathEffect[] mEffects;
            private int[] mColors;
            private float mPhase = 3;
    
            private static void makeEffects(PathEffect[] e, float phase) {
                e[0] = null;     // no effect
                e[1] = new CornerPathEffect(10);
                e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase);
                e[3] = new PathDashPathEffect(makePathDash(), 12, phase,
                                              PathDashPathEffect.Style.MORPH);
                e[4] = new ComposePathEffect(e[2], e[1]);
                e[5] = new ComposePathEffect(e[3], e[1]);
            }
    
            public SampleView(Context context) {
                super(context);
                setFocusable(true);
                setFocusableInTouchMode(true);
    
                mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
                mPaint.setStyle(Paint.Style.STROKE);
                mPaint.setStrokeWidth(6);
    
                mPath = makeFollowPath();
    
                mEffects = new PathEffect[6];
    
                mColors = new int[] { Color.BLACK, Color.RED, Color.BLUE,
                                      Color.GREEN, Color.MAGENTA, Color.BLACK
                                    };
            }
    
            @Override protected void onDraw(Canvas canvas) {
                canvas.drawColor(Color.WHITE);
    
                RectF bounds = new RectF();
                mPath.computeBounds(bounds, false);
                canvas.translate(10 - bounds.left, 10 - bounds.top);
    
                makeEffects(mEffects, mPhase);
                invalidate();
    
                for (int i = 0; i < mEffects.length; i++) {
                    mPaint.setPathEffect(mEffects[i]);
                    mPaint.setColor(mColors[i]);
                    canvas.drawPath(mPath, mPaint);
                    canvas.translate(0, 28);
                }
            }
    
            @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
                switch (keyCode) {
                    case KeyEvent.KEYCODE_DPAD_CENTER:
                        mPath = makeFollowPath();
                        return true;
                }
                return super.onKeyDown(keyCode, event);
            }
    
            private static Path makeFollowPath() {
                Path p = new Path();
                p.moveTo(0, 0);
                for (int i = 1; i <= 15; i++) {
                    p.lineTo(i*20, (float)Math.random() * 35);
                }
                return p;
            }
    
            private static Path makePathDash() {
                Path p = new Path();
                p.moveTo(-6, 4);
                p.lineTo(6,4);
                p.lineTo(6,3);
                p.lineTo(-6, 3);
                p.close();
                p.moveTo(-6, -4);
                p.lineTo(6,-4);
                p.lineTo(6,-3);
                p.lineTo(-6, -3);
                return p;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题