我可以将自定义控件作为标记添加到OSMBNUSPACK吗?
我在Android xml文件MyMarkerItem.xml 中创建了一些按钮和图像
我想要MyMarker.setDesign(R.layout.MyMarkerItem);
感谢
好吧,我知道你希望标记图标本身不是一个简单的位图,而是一个布局。
您可以使用标记信息窗口"而不是"标记图标。
首先,创建一个新的类CustomInfoWindow,它继承了MarkerInfoWindow(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(
- 根据布局的"外观",将信息窗口"锚点"设置为最合适、最自然的位置:设置信息窗口锚点(锚_CENTER、锚_CENTER(可能吗
- 强制打开信息窗口:showInfoWindow((
所有这些步骤都相当简单。
但是,我想当用户点击你的布局按钮时,你会预料到一些行为。因此,在CustomInfoWindow代码中,您肯定需要按照本教程进行一些工作=>。
Osmdroid中的标记实际上不是android视图,因此不可能向其中添加其他组件。它们基本上只是一个图像。
简单且建议的解决方案
不过,您可以将组件添加到单击后显示的MarkerInfoWindow中。
marker.setInfoWindow(new MarkerInfoWindow(R.layout.MyMarkerItem, mapView));
可能的"真实"解决方案
如果你真的需要这样的行为——这意味着你真的想要在地图上显示多个按钮作为"标记",并让用户有机会点击它们——那么你应该可以创建自己的marker类实现。换言之,您必须实现自己的OverlayWithIW或Overlay子类,并覆盖(主要(draw
方法(它应该将按钮绘制到画布上(和onSingleTapConfirmed
方法,在那里您需要正确检测用户单击的按钮并调用相关操作。试着浏览Marker类的源代码,这是一个很好的例子。
但请记住:这是一项高级任务。如果操作不当,与在画布上绘制相关的一切都可能导致性能问题。会有一些边缘案例需要你去处理。您可能还需要解决和调试其他问题。我不会向初学者建议这样的解决方案。
现在是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_title
、bubble_description
、bubble_subdescription
、bubble_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
已经超过了我作为前端工程师的时间,所以我将把它留给读者在这里进行实验。