Question

I am creating a simple map application using OpenStreetMap. I have opened up the map in the MapView and added markers on the map. All this is working fine. Now what I what is when a user clicks on a marker, a description box should pop up having the name, description and an imageview of the place.

The MainActivity:

public class MainActivity extends Activity {

     MyItemizedOverlay myItemizedOverlay = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

         MapView mapView = (MapView) findViewById(R.id.mapview);
            mapView.setBuiltInZoomControls(true);

            Drawable marker=getResources().getDrawable(R.drawable.pin_for_map);
            int markerWidth = marker.getIntrinsicWidth();
            int markerHeight = marker.getIntrinsicHeight();
            marker.setBounds(0, markerHeight, markerWidth, 0);

            ResourceProxy resourceProxy = new DefaultResourceProxyImpl(getApplicationContext());

            myItemizedOverlay = new MyItemizedOverlay(marker, resourceProxy);
            mapView.getOverlays().add(myItemizedOverlay);

            GeoPoint myPoint1 = new GeoPoint(0*1000000, 0*1000000);
            myItemizedOverlay.addItem(myPoint1, "myPoint1", "myPoint1");
            GeoPoint myPoint2 = new GeoPoint(50*1000000, 50*1000000);
            myItemizedOverlay.addItem(myPoint2, "myPoint2", "myPoint2");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

The MyItemizedOverlay class:

public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> {

 private ArrayList<OverlayItem> overlayItemList = new ArrayList<OverlayItem>();

 public MyItemizedOverlay(Drawable pDefaultMarker,
   ResourceProxy pResourceProxy) {
  super(pDefaultMarker, pResourceProxy);
  // TODO Auto-generated constructor stub
 }

 public void addItem(GeoPoint p, String title, String snippet){
  OverlayItem newItem = new OverlayItem(title, snippet, p);
  overlayItemList.add(newItem);
  populate(); 
 }

 @Override
 public boolean onSnapToItem(int arg0, int arg1, Point arg2, IMapView arg3) {
  // TODO Auto-generated method stub
  return false;
 }

 @Override
 protected OverlayItem createItem(int arg0) {
  // TODO Auto-generated method stub
  return overlayItemList.get(arg0);
 }

 @Override
 public int size() {
  // TODO Auto-generated method stub
  return overlayItemList.size();
 }

} 

The activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="5dp"
        android:text="@string/hello_world"
        tools:context=".MainActivity" />

    <org.osmdroid.views.MapView
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"/>

</RelativeLayout>

The manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.openstreetmaptutorial"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.openstreetmaptutorial.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Please import the osmdroid-android-4.1.jar and slf4j-android-1.5.8.jar libraries and run the project.

I had referred this link.

I want the output to be something like:

Image

Please suggest me how to make the popup as depicted above

Was it helpful?

Solution

I have solved the problem. Firstly, I have created a layout called custom_dialog.xml. The code:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    android:background="@drawable/bonuspack_bubble">

   <TextView
        android:id="@+id/map_popup_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="3dp"
        android:layout_marginTop="3dp"
        android:text="TextView" 
        android:textSize="15dp"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/map_popup_body"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/map_popup_header"
        android:layout_below="@+id/map_popup_header"
        android:layout_marginTop="5dp"
        android:text="TextView" 
        android:textSize="12dp"/>

    <ImageView
        android:id="@+id/map_more_info_imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/map_popup_body"
        android:layout_marginRight="5dp"
        android:src="@drawable/moreinfo_arrow" />

</RelativeLayout>

I have edited MapItemizedOverlay class like this:

public class MapItemizedOverlay extends ItemizedOverlay<OverlayItem> {
    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
    private Context mContext;

    public MapItemizedOverlay(Drawable defaultMarker, Context context) {
        // super(boundCenterBottom(defaultMarker));
        super(defaultMarker, new DefaultResourceProxyImpl(context));
        mContext = context;
    }

    public void addOverlay(OverlayItem overlay) {
        mOverlays.add(overlay);
        populate();
    }

    @Override
    protected OverlayItem createItem(int i) {
        return mOverlays.get(i);
    }

    @Override
    public int size() {
        return mOverlays.size();
    }

    protected boolean onTap(int index) {
        OverlayItem item = mOverlays.get(index);

        Log.d("Title", item.getTitle());
        Log.d("Snippet", item.getSnippet());
        Log.d("Id", item.getUid());


         //set up dialog
        Dialog dialog = new Dialog(mContext);
        dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
        dialog.setContentView(R.layout.custom_dialog);
        //dialog.setTitle("This is my custom dialog box");

        dialog.setCancelable(true);
        //there are a lot of settings, for dialog, check them all out!

        //set up text
        TextView map_popup_header = (TextView) dialog.findViewById(R.id.map_popup_header);
        map_popup_header.setText(item.getTitle());

        TextView map_popup_body = (TextView) dialog.findViewById(R.id.map_popup_body);
        map_popup_body.setText(item.getSnippet());

        //set up button
        ImageView imgMoreInfo = (ImageView) dialog.findViewById(R.id.map_more_info_imageView);
        imgMoreInfo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              Log.d("Clicked", "more info");
            }
        });
        //now that the dialog is set up, it's time to show it    
        dialog.show();

        return true;
    }

    // boolean onTap(GeoPoint p, MapView mapView)
    // {
    // return false;
    // }

    // @Override
    // public boolean onSnapToItem(int arg0, int arg1, Point arg2, MapView arg3)
    // {
    // // TODO Auto-generated method stub
    // return false;
    // }

    @Override
    public boolean onSnapToItem(int arg0, int arg1, Point arg2, IMapView arg3) {
        // TODO Auto-generated method stub
        return false;
    }

}

The method to add the bubble on the map:

// =====For showing restaurant location======================//
    public void showFoodJoint(String foodJointId,double foodJointLat, double foodJointLon, String foodJointName, String foodJointDescription)
    {
        Drawable restaurantLocationDrawable = this.getResources().getDrawable(
                R.drawable.pin_for_restaurant_location);
        MapItemizedOverlay itemizedoverlayForRestaurant = new MapItemizedOverlay(
                restaurantLocationDrawable, this);

        GeoPoint myPoint1 = new GeoPoint(foodJointLat, foodJointLon);
        OverlayItem overlayitem2 = new OverlayItem(foodJointId,foodJointName,foodJointDescription, myPoint1);

        itemizedoverlayForRestaurant.addOverlay(overlayitem2);

        mapOverlays.add(itemizedoverlayForRestaurant);
    }

    // =====For showing restaurant location======================//

This method should be added in the main activity.

Output:

Output image

OTHER TIPS

You could take a look at OSMBonusPack, https://code.google.com/p/osmbonuspack/

Change MyItemizedOverlay and make it extend the Marker class. Then, make another custom class, that extends MarkerInfoWindow. Some samples below:

1.CustomMarker class:

private static class CustomMarker extends Marker
    {

        public CustomMarker(MapView mapView, ResourceProxy resourceProxy) {
            super(mapView, resourceProxy);
        }

        public CustomMarker(MapView mapView) {
            super(mapView);
        }

        public String name;
        public String desc;
    }
  1. CustomInfoWindow class:

    public class CustomInfoWindow extends MarkerInfoWindow {

        private CustomMarker marker;
    
        public CustomInfoWindow(MapView mapView) {
            super(R.layout.bonuspack_bubble, mapView);    
        }
    
        @Override
        public void onOpen(Object item) {
            marker = (CustomMarker) item;
            Button btn = (Button) (mView.findViewById(R.id.bubble_moreinfo));
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (marker != null) {
                        if (marker.name!= null && marker.desc!= null) {
                            btn.setText(title);
                            btn.setDescription(desc);
                        }
                    }
                }
            });
        }
    }
    
  2. Somewhere in your code then:

    public class MyClass extends Activity {
    
    public MapView mapView;
    
    @Override
    protected void onCreate(Bundle load)
    {
        super.onCreate(load);
        setContentView(R.layout.activity_map);
        mapView = (MapView)findViewById(R.id.map);
    
    }
    
    ....
    
    
    CustomMarker marker = new CustomMarker(mapView);//you can also pass "this" as argument I believe
    marker.setPosition(locatedGeoPoint);
    marker.name = "nomnom";
    marker.desc = "nomming";
    marker.setInfoWindow(new CustomInfoWindow((mapView));
    marker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
                            @Override
                            public boolean onMarkerClick(Marker item, MapView arg1) {
                                item.showInfoWindow();
                                return true;
                            }
                        });
    }
    

I posted a similar answer here: osmdroid workaround for the classic markers overlapping

R.layout.activity_map is a simple XML layout, with the MapView:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<org.osmdroid.views.MapView
      android:id="@+id/map"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"/>
</RelativeLayout>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top