【问题标题】:Google Map Marker with custom background and text具有自定义背景和文本的谷歌地图标记
【发布时间】:2016-09-20 13:29:39
【问题描述】:

我正在尝试自定义地图标记,以便它可以显示 3 个主要功能:

  • 9patch 可绘制为背景
  • 自定义文本
  • 可选的可在文本左侧绘制(有些标记有,有些没有)

我使用了 android google map utils library 中的 IconGenerator,但不知何故,标记的整个可点击区域都受到了影响。标记周围的一个非常大的区域是可点击的并激活标记。它还存在内容填充和重力属性的问题。

我已经在地图上添加了自定义 hack,以便在不打开信息窗口的情况下将标记放在前面(我设置了一个没有显示内容的信息窗口,并且我在标记单击事件侦听器中调用了 showInfoWindow) .

如何手动为标记创建图标并避免其周围的大可点击区域出现问题?

我也试过here描述的实现,基本上就是drawTextToBitmap()方法:

private Bitmap drawTextToBitmap(@DrawableRes int backgroundRes, String text) {
        Resources resources = getResources();
        float scale = resources.getDisplayMetrics().density;
        Bitmap bitmap = BitmapFactory.decodeResource(resources, backgroundRes);
        android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();

        if (bitmapConfig == null) {
            bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
        }
        bitmap = bitmap.copy(bitmapConfig, true);
        Canvas canvas = new Canvas(bitmap);

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        // SET FONT COLOR (e.g. WHITE -> rgb(255,255,255))
        paint.setColor(Color.rgb(255, 255, 255));
        // SET FONT SIZE (e.g. 15)
        paint.setTextSize((int) (15 * scale));
        // SET SHADOW WIDTH, POSITION AND COLOR (e.g. BLACK)
        paint.setShadowLayer(1f, 0f, 1f, Color.BLACK);

        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        int x = (bitmap.getWidth() - bounds.width()) / 2;
        int y = (bitmap.getHeight() + bounds.height()) / 2;
        canvas.drawText(text, x, y, paint);

        return bitmap;
    }

但它并没有按预期工作,因为我的文本比背景大,而且我也不知道如何在文本的左侧添加资源。

这是我正在使用的 IconGenerator 的实现:

private BitmapDescriptor getBitmapDescriptorForProduct(@NonNull final MyCustomObject product, boolean isActive) {
    if (product.shouldDisplayWithLabel) {
        // We use an custom layout for displaying markers on the map
        @SuppressLint("InflateParams") View view =
                LayoutInflater.from(getActivity()).inflate(R.layout.my_custom_label, null);

        // Get the text view which will display the text 
        TextView label = (TextView) view.findViewById(R.id.text);
        // Set the left drawable if needed
        label.setCompoundDrawablesWithIntrinsicBounds(product.shouldDisplayWithDrawable ? R.drawable.my_custom_drawable : 0, 0,
                                                      0, 0);
        // Set the text for the label
        label.setText(product.label);
        label.setBackgroundResource(R.drawable.my_custom_background);

        // Set the layout for the icon
        mIconGenerator.setContentView(view); // set the custom layout

        // We don't want the default background
        mIconGenerator.setBackground(null);
        // Disable the content padding as we handle it in the view and in the 9patch resources
        mIconGenerator.setContentPadding(0, 0, 0, 0);

        // Make the icon and create the BitmapDescriptor necessary for the marker creation
        Bitmap icon = mIconGenerator.makeIcon();
        return BitmapDescriptorFactory.fromBitmap(icon);
    } else {
        // Lazy initialization for the normal markers
        if (null == simpleMarkerIcon) {
            simpleMarkerIcon = BitmapDescriptorFactory.fromResource(R.drawable.my_simple_marker);
        }

        // Reuse the bitmap for the simple markers that will be displayed on the map.
        return simpleMarkerIcon;
    }
} 

乐: @Harpreet,使用您的解决方案时标记图标的外观如下:

如您所见,视图的属性在位图中没有正确显示。

【问题讨论】:

    标签: android google-maps android-custom-view marker nine-patch


    【解决方案1】:
    public static Bitmap createDrawableFromView(Context context, View view) {
            DisplayMetrics displayMetrics = new DisplayMetrics();
            ((Activity) context).getWindowManager().getDefaultDisplay()
                    .getMetrics(displayMetrics);
            view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT));
            view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
            view.layout(0, 0, displayMetrics.widthPixels,
                    displayMetrics.heightPixels);
            view.buildDrawingCache();
            Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(),
                    view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    
            Canvas canvas = new Canvas(bitmap);
            view.draw(canvas);
    
            return bitmap;
        }
    

    注意:- 只需填写 Context 并将您完整的自定义视图/布局添加为 View

    的对象

    它会帮助你。

    【讨论】:

    • 看来这个方法是非常占用内存的,运行这个方法我得到 OOM 异常 99% 的时间。
    • 我还使用您的方法添加了一个带有位图结果的SS。
    • 如果您有多个标记要同时显示在地图上,您也需要使用 Google Clustering。
    • 应用程序的设计不依赖于集群,因此它目前不是我的选择。我已经更新了问题并包含了 IconGenerator 的实现。这和我需要的很接近,但是marker的触摸面积很大。
    猜你喜欢
    • 2016-10-24
    • 2016-02-22
    • 1970-01-01
    • 2014-06-23
    • 2013-08-21
    • 2014-12-21
    • 2020-04-28
    相关资源
    最近更新 更多