【问题标题】:How can I create a speech-bubble border for a Google Marker Custom Icon using Picasso?如何使用毕加索为 Google 标记自定义图标创建语音气泡边框?
【发布时间】:2016-04-07 19:31:15
【问题描述】:

如何使用 Picasso 和 Google Marker Custom Icon 来实现这个功能?

我知道如何在图像上使用毕加索,但我不知道如何在底部和边框上添加那个“标记图标”。

Picasso.with(mContext)
            .load(url)
            .resize(250, 250)
            .centerInside()
            .into(new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    Marker driver_marker = mMap.addMarker(new MarkerOptions()
                            .position(new LatLng(Double.parseDouble(lat), Double.parseDouble(lng)))
                            .icon(BitmapDescriptorFactory.fromBitmap(bitmap))
                            .title(name)
                            .snippet(address)
                    );


                    @Override
                    public void onBitmapFailed (Drawable errorDrawable){
                    }

                    @Override
                    public void onPrepareLoad (Drawable placeHolderDrawable){
                    }
                });
            }

我在 onBitmapLoaded 中添加了这个:

Paint paint = new Paint();
    paint.setColor(Color.YELLOW);
    paint.setStrokeWidth(10);
    paint.setShadowLayer(5, 0, 1, Color.RED);

    Canvas canvas = new Canvas(bitmap);
    canvas.drawLine(0, 0, canvas.getWidth(), 0, paint);
    canvas.drawLine(0, 0, 0, canvas.getHeight(), paint);
    canvas.drawLine(0, canvas.getHeight(), canvas.getWidth(), canvas.getHeight(), paint);
    canvas.drawLine(canvas.getWidth(), 0, canvas.getWidth(), canvas.getHeight(), paint);

这似乎添加了边框,但是如何在画布上添加倒金字塔?谢谢,在那之后,我几乎完成了! :D

【问题讨论】:

  • 那里没有回答
  • 充其量,我能得到的是我从位图制作一个画布,然后我如何用画布创建边框?
  • 创建您自己的转换类,将 Paint 对象绘制到 Canvas。你可以从这个开始:gist.github.com/aprock/6213395
  • 尝试将anchor设置为driver_marker(Marker)driver_marker.anchor(0.5f, 0.5f);here
  • 好吧,我添加了画布和 Paint,这似乎可以创建边界,现在我需要的是带有画布的倒金字塔。不知道怎么样,哈哈。

标签: android google-maps android-layout google-maps-markers


【解决方案1】:

这是我开始工作的转换类。它缺少圆角半径和任何渐变,但底部有倒金字塔,应该作为一个很好的起点。

这里是转换类:

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";
    }
}

对毕加索的呼唤:

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

目标:

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) {

    }
};

结果:

【讨论】:

  • 不错的答案+1。告诉我一件事,如果我希望那个标记在其下方带有小箭头,该怎么办?
  • @ZubairAhmed 你有没有找到下面带有小箭头的圆形标记的解决方案??
  • @Rahul 是的,我想我是通过改变半径来做到的,但这是一个非常古老的项目,我会找出源头并告诉你
  • @Rahul 我相信这就是你要找的东西:stackoverflow.com/a/50144688/4409409
【解决方案2】:

在kotlin中可以这样设置..

  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;

    }

【讨论】:

    【解决方案3】:

    这里的标记视图是您的自定义标记布局

        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)))
    

    使用此函数从视图转换位图

    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
        }
    

    【讨论】:

      【解决方案4】:

      我参加聚会有点晚了,但上述所有解决方案都不起作用或已弃用。

      如果你想要类似于下图的东西,那么你只需要遵循这 3 个简单的步骤。

      1.创建要显示为标记的 XML 布局

      我已经创建了custom_location_marker.xml 布局。

      2。只需将此函数复制并粘贴到您的地图片段/地图活动中

          private fun createDrawableFromView(): Bitmap {
          val customMarkerView: View = View.inflate(
              requireActivity(),
              R.layout.custom_location_marker, null
          )
      
          customMarkerView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
          customMarkerView.layout(
              0,
              0,
              customMarkerView.measuredWidth,
              customMarkerView.measuredHeight
          )
      
          val bitmap =
              Bitmap.createBitmap(
                  customMarkerView.width,
                  customMarkerView.height,
                  Bitmap.Config.ARGB_8888
              )
          val canvas = Canvas(bitmap)
          customMarkerView.draw(canvas)
          return bitmap
      }
      

      3.然后当地图准备好时,只需调用此函数在地图中添加标记:

      googleMap.addMarker(MarkerOptions().position(LatLng(24.0, 260.0)).icon(
              BitmapDescriptorFactory
                  .fromBitmap(createDrawableFromView())
          ))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-30
        • 2014-09-18
        • 1970-01-01
        • 1970-01-01
        • 2016-07-08
        • 1970-01-01
        • 2019-04-02
        • 1970-01-01
        相关资源
        最近更新 更多