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

前端 未结 3 549
后悔当初
后悔当初 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:

    0 讨论(0)
  • 2020-12-06 02:56

    You can set in kotlin like this..

      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
    
            mapView.getMapAsync { googleMap ->
                googleMap1 = googleMap as GoogleMap
                addCustomMarker()
            }
    
        }
    
    
     private fun addCustomMarker() {
            Log.d("addCustomMarker", "addCustomMarker()")
            if (googleMap1 == null) {
                return
            }
            // adding a marker on map with image from  drawable
            googleMap1.addMarker(
                MarkerOptions()
                    .position(LatLng(23.0225 , 72.5714))
                    .icon(BitmapDescriptorFactory.fromBitmap(getMarkerBitmapFromView()))
            )
        }
    
    
    
        private fun getMarkerBitmapFromView(): Bitmap? {
            val customMarkerView: View? = layoutInflater.inflate(R.layout.view_custom_marker, null)
    //        val markerImageView: ImageView =
    //            customMarkerView.findViewById<View>(R.id.profile_image) as ImageView
            customMarkerView?.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED );
            customMarkerView?.layout(0, 0, customMarkerView.measuredWidth, customMarkerView.measuredHeight);
            customMarkerView?.buildDrawingCache();
            val returnedBitmap = Bitmap.createBitmap(
                customMarkerView!!.measuredWidth, customMarkerView.measuredHeight,
                Bitmap.Config.ARGB_8888
            )
            val canvas = Canvas(returnedBitmap)
            canvas.drawColor(Color.WHITE, PorterDuff.Mode.SRC_IN)
            val drawable = customMarkerView.background
    
            drawable?.draw(canvas);
            customMarkerView.draw(canvas);
            return returnedBitmap;
    
        }
    
    0 讨论(0)
  • 2020-12-06 03:04

    here marker view is your custom marker layout

        val view = LayoutInflater.from(context).inflate(R.layout.marker_view, 
        null,false)
    
        val bitmap = getBitmapFromView(view)
    
        // Uses a custom icon.
         mSydney = mMap.addMarker(MarkerOptions()
            .position(SYDNEY)
            .title("Sydney")
            .snippet("Population: 4,627,300")
            .icon(BitmapDescriptorFactory.fromResource(bitmap)))
    

    use this function to convert bitmap from view

    private fun getBitmapFromView(view: View): Bitmap {
            view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
            val bitmap = Bitmap.createBitmap(view.measuredWidth, view.measuredHeight,
                    Bitmap.Config.ARGB_8888)
            val canvas = Canvas(bitmap)
            view.layout(0, 0, view.measuredWidth, view.measuredHeight)
            view.draw(canvas)
            return bitmap
        }
    
    0 讨论(0)
提交回复
热议问题