添加自定义控件作为标记 OSMDROID BONUS PACK

Add Custom Control as Marker OSMDROID BONUS PACK

我可以将自定义控件作为标记添加到 OSMBONUSPACK 吗?

我在名为 MyMarkerItem.xml

的 Android xml 文件中创建了一些按钮和图像

我想要 MyMarker.setDesign(R.layout.MyMarkerItem);

谢谢

Osmdroid 中的标记实际上 android 视图,因此无法向其中添加其他组件。它们基本上只是一个图像。

简单且建议的解决方案

不过,您可以将组件添加到 MarkerInfoWindow,点击后会显示。

marker.setInfoWindow(new MarkerInfoWindow(R.layout.MyMarkerItem, mapView));

可能"real"解决方案

如果您真的需要这样的行为——这意味着您确实需要在地图上显示多个按钮作为 "marker" 并让用户有机会点击它们——应该可以创建您自己的实现一个类似标记的 class。换句话说,您必须实现自己的 OverlayWithIW or Overlay and override (mainly) the draw method (which should draw your buttons to a canvas) and the onSingleTapConfirmed method, where you would need to detect properly on which button user clicked and call the related action. Try to go through source of the Marker class 的子 class,这是一个很好的例子。

但请记住:这是一项高级任务。如果未正确完成,与 canvas 绘图相关的所有内容都可能导致性能问题。将有您必须涵盖的边缘情况。您可能需要解决和调试其他问题。我不会向初学者建议这样的解决方案。

好的,我明白你希望标记图标本身不是简单的位图,而是布局。

您可以使用标记图标的标记信息窗口"instead"。

首先,创建一个新的 class CustomInfoWindow,它继承自 MarkerInfoWindow - 标记的默认信息窗口,并使用您自己的布局:

public class CustomInfoWindow extends MarkerInfoWindow {
    public CustomInfoWindow(MapView mapView) {
        super(my_own_layout, mapView);
    }
}

CustomInfoWindow myCustomInfoWindow = new CustomInfoWindow(mapView);

然后,在创建标记之后,执行以下操作:

  • 将标记图标设置为 1x1 像素大小的位图,完全透明:setIcon(mySmall_InvisibleIcon)
  • 将标记信息窗口设置为您自己的:setInfoWindow(myCustomInfoWindow)
  • 根据您的 "look" 布局,将信息窗口 "anchor" 设置到最合适和自然的位置:setInfoWindowAnchor(ANCHOR_CENTER, ANCHOR_CENTER) 也许吧?
  • 强制打开信息窗口:showInfoWindow()

所有这些步骤都相当简单。

但是,我猜您希望当用户单击您的布局按钮时会发生某些行为。 因此,在您的 CustomInfoWindow 代码中,您肯定需要做一些工作 => 按照 this tutorial

现在是 2021 年 8 月,我想添加一个任意布局作为我的标记项。就像 OP 在这里要求的那样。

我尝试了https://whosebug.com/a/53003664/866333简单和建议的解决方案

marker.setInfoWindow(new MarkerInfoWindow(R.layout.MyMarkerItem, mapView));

单击它时出现运行时异常:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference.

为了参数的缘故,我将布局精简为单个 TextView 小部件,但错误仍然存​​在。


我放弃那个答案并尝试接受的答案:https://whosebug.com/a/53216542/866333

public class CustomInfoWindow extends MarkerInfoWindow {
    public CustomInfoWindow(MapView mapView) {
        super(my_own_layout, mapView);
    }
}

CustomInfoWindow myCustomInfoWindow = new CustomInfoWindow(mapView);

使用与之前相同的my_own_layout,我们称它为R.layout.my_info_window

我得到同样的错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

我深入研究了 AS-reverse 设计的(感谢 AS)源代码,发现这个错误的原因是传递给 MarkerInfoWindow super class 构造函数的布局具有特殊的身份证件要求。

我们的布局中必须有这些 id:bubble_titlebubble_descriptionbubble_subdescriptionbubble_image

这是一个最小的工作示例:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/bubble_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        tools:layout_editor_absoluteX="153dp"
        tools:layout_editor_absoluteY="20dp" />

    <TextView
        android:id="@+id/bubble_description"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        tools:layout_editor_absoluteX="153dp"
        tools:layout_editor_absoluteY="39dp" />

    <TextView
        android:id="@+id/bubble_subdescription"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        tools:layout_editor_absoluteX="153dp"
        tools:layout_editor_absoluteY="58dp" />

    <ImageView
        android:id="@+id/bubble_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@drawable/marker_cluster"
        tools:layout_editor_absoluteX="145dp"
        tools:layout_editor_absoluteY="76dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

太棒了!

我什至可以尝试通过附加另一个小部件来自定义:

    <TextView
        android:id="@+id/anothertexttestview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="look ma!"
        tools:layout_editor_absoluteX="153dp"
        tools:layout_editor_absoluteY="125dp" />

absoluteY 被忽略并叠加在我以编程方式设置的唯一文本标题上。 IOW,小部件不是纯粹的声明性 xml。恐怕 ConstraintLayout 是我作为前端工程师的时间,所以我会把它留给 reader 从这里开始试验。