How can I create a speech-bubble border for a Google Marker Custom Icon using Picasso?

前端 未结 3 679
后悔当初
后悔当初 2020-12-06 02:27

How can I use Picasso and Google Marker Custom Icon to achieve this feature?

I know how to use Picasso for the image, but I don\'t know how to add that \"ma

3条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-06 02:52

    Here is a transformation class that I got working. It's lacking the corner radius and any gradients, but it has the inverted pyramid on the bottom, and it should serve as a good starting point.

    Here is the transformation class:

    import android.graphics.Bitmap;
    import android.graphics.BitmapShader;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.RectF;
    import android.graphics.Shader;
    
    public class BubbleTransformation implements com.squareup.picasso.Transformation {
        private static final int outerMargin = 40;
        private final int margin;  // dp
    
        // margin is the board in dp
        public BubbleTransformation(final int margin) {
            this.margin = margin;
        }
    
        @Override
        public Bitmap transform(final Bitmap source) {
            Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(output);
    
            Paint paintBorder = new Paint();
            paintBorder.setColor(Color.CYAN);
            paintBorder.setStrokeWidth(margin);
            canvas.drawRoundRect(new RectF(outerMargin, outerMargin, source.getWidth() - outerMargin, source.getHeight() - outerMargin), 0, 0, paintBorder);
    
            Paint trianglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    
            trianglePaint.setStrokeWidth(2);
            trianglePaint.setColor(Color.CYAN);
            trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE);
            trianglePaint.setAntiAlias(true);
    
            Path triangle = new Path();
            triangle.setFillType(Path.FillType.EVEN_ODD);
            triangle.moveTo(outerMargin, source.getHeight() / 2);
            triangle.lineTo(source.getWidth()/2,source.getHeight());
            triangle.lineTo(source.getWidth()-outerMargin,source.getHeight()/2);
            triangle.close();
    
            canvas.drawPath(triangle, trianglePaint);
    
            final Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
            canvas.drawRoundRect(new RectF(margin+outerMargin, margin+outerMargin, source.getWidth() - (margin + outerMargin), source.getHeight() - (margin + outerMargin)), 0, 0, paint);
    
            if (source != output) {
                source.recycle();
            }
    
            return output;
        }
    
        @Override
        public String key() {
            return "rounded";
        }
    }
    

    The call to Picasso:

     Picasso.with(getActivity())
                .load(user_photo_url)
                .resize(250,250)
                .centerCrop()
                .transform(new BubbleTransformation(20))
                .into(mTarget);
    

    The Target:

    Target mTarget = new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            Marker driver_marker = mMap.addMarker(new MarkerOptions()
                            .position(latLng)
                            .icon(BitmapDescriptorFactory.fromBitmap(bitmap))
                            .title("test")
                            .snippet("test address")
            );
        }
    
        @Override
        public void onBitmapFailed(Drawable errorDrawable) {
            Log.d("picasso", "onBitmapFailed");
        }
    
        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {
    
        }
    };
    

    Result:

提交回复
热议问题