简体   繁体   中英

Add Custom Control as Marker OSMDROID BONUS PACK

Can I add Custom Control as Marker to OSMBONUSPACK?

I create some Buttons and image in Android xml file Named MyMarkerItem.xml

I would like something like MyMarker.setDesign(R.layout.MyMarkerItem);

Thanks

OK, I understand that you want the marker icon itself to be not a simple bitmap, but a layout.

What you can do is to use the marker infowindow "instead" of the marker icon.

First of all, create a new class CustomInfoWindow which inherits from MarkerInfoWindow - the default InfoWindow for Markers, and uses your own layout:

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

CustomInfoWindow myCustomInfoWindow = new CustomInfoWindow(mapView);

Then, just after creating your Marker, do that:

  • Set a marker icon as a 1x1 pixel size bitmap, fully transparent: setIcon(mySmall_InvisibleIcon)
  • Set the marker infowindow to your own: setInfoWindow(myCustomInfoWindow)
  • Set the infowindow "anchor" to the most appropriate and natural position, depending on the "look" of your layout: setInfoWindowAnchor(ANCHOR_CENTER, ANCHOR_CENTER) maybe?
  • Force the opening of the infowindow: showInfoWindow()

All these steps are fairly simple.

But then, I guess you expect some behaviour to happen when the user will click on your layout buttons. So, inside your CustomInfoWindow code, you will certainly have to do some work => follow this tutorial .

Markers in Osmdroid arent actually android views and therefore it's not possible to add other components into them. They are basically just an image.

Simple and suggested solution

You can add your components to a MarkerInfoWindow which is displayed after a click, though.

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

Possible "real" soluiton

If you really need such behaviour - meaning you really need multiple buttons displayed on a map as a "marker" and give the user the opportunity to click on them - it should be possible to create your own implementation of a Marker-like class. In other words, you would have to implement your own subclass of 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 , it's a good example.

But keep in mind: this is an advanced task. Everything related to drawing on canvas can lead to performance issues if it's not done properly. There will be edge cases you'll have to cover. There may be other problems you'll need to solve and debug. I would not suggest such a solution to a beginner.

It's August 2021 and I wanted to add an arbitrary layout as my marker item. Much as the OP is asking for here.

I tried the Simple and suggested solution of https://stackoverflow.com/a/53003664/866333 :

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

I get a runtime exception when I click it:

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

I refine my layout down to a single TextView widget for arguments sake and the error persists.


I give up on that answer and attempt the accepted one: 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);

Using the same my_own_layout as before, let's call it R.layout.my_info_window

I get the same error:

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

I dug into the AS-reverse engineered (thanks AS) source code to discover the reason for this error is that the layout being passed to the MarkerInfoWindow super class constructor has particular id requirements.

We must have these ids in our layout: bubble_title , bubble_description , bubble_subdescription , bubble_image

Here is a minimal working example:

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

That works great!

I can even attempt to customise by appending another widget:

    <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" />

The absoluteY is ignored and superimposed on the only text I set programmatically, the title. IOW, the widget isn't purely declarative xml. I'm afraid ConstraintLayout is after my time as a front end engineer so I'll leave it to the reader to experiment from here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM