【问题标题】:Add Custom Control as Marker OSMDROID BONUS PACK添加自定义控件作为标记 OSMDROID BONUS PACK
【发布时间】:2020-04-22 16:11:23
【问题描述】:

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

我在名为 MyMarkerItem.xml 的 Android xml 文件中创建了一些按钮和图像

我想要MyMarker.setDesign(R.layout.MyMarkerItem);之类的东西

谢谢

【问题讨论】:

    标签: java android osmdroid osmbonuspack


    【解决方案1】:

    好的,我知道您希望标记图标本身不是简单的位图,而是布局。

    您可以做的是使用标记信息窗口“而不是”标记图标。

    首先,创建一个继承自 MarkerInfoWindow 的新类 CustomInfoWindow - Markers 的默认 InfoWindow,并使用您自己的布局:

    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)
    • 根据布局的“外观”,将信息窗口“锚点”设置为最合适和最自然的位置: setInfoWindowAnchor(ANCHOR_CENTER, ANCHOR_CENTER) 可能吗?
    • 强制打开信息窗口:showInfoWindow()

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

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

    【讨论】:

    • 我测试了它,代码很棒而且很简单。我有一个问题,当我更改标记位置时,它虽然重复(没有新实例)但绘制它重复了。对于标记 A,当我使用它移动它时,我将首先移动 A 和 A'。像按钮点击A'这样的任何动作都会处理标记A。这正常吗?谢谢
    • 不是很容易理解...你能改写正确吗?此外,确保为每个标记创建并设置一个新的 customInfoWindow(不要在标记之间共享相同的信息窗口)。
    【解决方案2】:

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

    简单的建议解决方案

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

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

    可能的“真实”解决方案

    如果您真的需要这样的行为 - 意味着您确实需要在地图上显示多个按钮作为“标记”并让用户有机会点击它们 - 应该可以创建自己的类似标记的实现班级。换句话说,您必须实现自己的 OverlayWithIWOverlay 子类并覆盖(主要)draw 方法(应该将您的按钮绘制到画布上)和 onSingleTapConfirmed 方法,您将需要正确检测用户单击了哪个按钮并调用相关操作。尝试通过source of the Marker class,这是一个很好的例子。

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

    【讨论】:

    • 那么,没有办法在同一个标​​记中添加多个按钮,例如使用它作为覆盖?
    • 你有什么推荐的 API 吗?
    • @nadjibnet 好吧,你不能用Marker 做到这一点。如果您真的需要这种行为,则可以实现您的自定义 Marker-like 类。我将扩展我的回复以添加一些提示。
    • 是的,例如:我需要在一个图标周围制作多个按钮
    • 没有堆栈跟踪。我得出了自己的结论并写了另一个答案。
    【解决方案3】:

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

    我尝试了https://stackoverflow.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://stackoverflow.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 逆向工程(感谢 AS)源代码,发现此错误的原因是传递给 MarkerInfoWindow 超类构造函数的布局具有特定的 id 要求。

    我们的布局中必须有这些 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 是在我担任前端工程师之后,所以我将把它留给读者从这里开始实验。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      相关资源
      最近更新 更多