22

Google Map API V2 - How do I keep a marker in the center of the screen while user is scrolling the map ?

My purpose is to let user choose a location. I use the following code to add a marker (it's from the com.example.mapdemo in Android SDK)

mMap.addMarker(new MarkerOptions()
    .position(new LatLng(0, 0))
    .title("Marker"));

How do I keep the marker in the center of the screen and then retrieve it's location?

Dan Getz
  • 8,774
  • 6
  • 30
  • 64
dong221
  • 3,390
  • 6
  • 29
  • 31

7 Answers7

18

I do not think that you can actually keep a marker in the middle of the screen and float it easily. My suggestion is to trick your user. Add your marker image onto the map like a button. you can place it in the middle of the screen using the xml layout. Then when your user selects a location just retrieve the gps coordinates from the middle of the screen.

On a side note you could also just make your marker draggable Then the user could drag it around the map.

mMap.addMarker(new MarkerOptions().position(coordinate)
                    .title("Your Title")
                    .snippet("Please move the marker if needed.")
                    .draggable(true)); 
doubleA
  • 2,446
  • 22
  • 45
9

How about?

mMap.setOnCameraChangeListener(new OnCameraChangeListener() {
        public void onCameraChange(CameraPosition arg0) {   
                mMap.clear();               
                mMap.addMarker(new MarkerOptions().position(arg0.target));
        }
});
Akexorcist
  • 2,287
  • 1
  • 16
  • 19
  • 2
    +1 Its working but with jerk. How could make marker movement smooth. – Ajay Oct 24 '14 at 21:15
  • 3
    This would work but the overhead of drawing with every time the CameraChangeListener is activated will cause the map UI to jerk. This is because the drawing occurs on the same thread. You'll have to find a way to draw the marker or add it without updating everytime a UI change occurs – Oladipo Olasemo May 22 '15 at 16:21
6

Option 1

I think the best option is move marker, when user move map...

googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
            @Override
            public void onCameraMove() {
                marker.setPosition(googleMap.getCameraPosition().target);//to center in map
            }
        });
//note marker is global

Option 2

or simple, in your layout, with relative layout put the fragment, and in above the icon of marker, you will calculate that marker will always in the middle of the map...

i think this is complicate, by size of screens, but the phone will not move every time the marker...

DarckBlezzer
  • 4,578
  • 1
  • 41
  • 51
4

This is the solution

    private GoogleMap mMap;
    private Marker markerCenter;

    @Override
    public void onMapReady(GoogleMap googleMap) {

       mMap = googleMap; 

       MarkerOptions markerOptions = new MarkerOptions();
       markerOptions.position(mMap.getCameraPosition().target);
       markerCenter = mMap.addMarker(markerOptions);

       mMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
          public void onCameraMove() {
              markerCenter.setPosition(mMap.getCameraPosition().target);
          }
       });

    }
Andres Marin
  • 251
  • 3
  • 12
2

This would actually be possible by overlaying a custom view on top of your map. You would write a class that extends View and you could override the draw() and onTouchEvent() methods of your view, such that it would draw (what looks like) a marker, over top of the middle of the map. When the user sets the marker, you would use a projection to translate the screen location of the marker into a LatLong on the map. You could then set a proper marker on the map (which would now be fixed to the geolocation).

As you can tell from the above, this is not the simplest process. I would suggest going with doubleA's solution, for ease of implementation.

gsysko
  • 988
  • 1
  • 8
  • 19
  • Before the new api was released it was actually simple to just float an image ontop of a map. You simply put it into the xml that contained the mapview. and it became a child that would be static on the screen while the map scrolled behind. I have been trying to do the same thing with the new api but i have been unable to do so. Is the custom view really the only solution to this? – doubleA Jan 06 '13 at 22:02
  • Yes, you should be able to use any existing widget (such as imageView) instead of a custom view, if it suits your purposes. BTW, I have [a similar question posted as to the recommended way of handling such layers in v2](http://stackoverflow.com/questions/14105531/what-is-the-suggested-way-of-implementing-overlays-in-v2-of-the-android-google-m). – gsysko Jan 07 '13 at 00:28
  • Something like this should work in a frame layout (being sure to add the overlay _after_ the map): ` ` – gsysko Jan 07 '13 at 01:13
0
Marker marker;//have a instance variable marker
mMap.setOnCameraChangeListener(new OnCameraChangeListener();
public void onCameraChange(CameraPosition cameraPosition) {   
                MarkerOptions options = new MarkerOptions()
                                        .position(cameraPosition.target);

                 if(marker != null){marker.remove();}
                 marker = mMap.addMarker(options);
}

This won't be smooth because,onCameraChange call back is not called during intermediate frames.It is called only after the camera is changed completely.

nagSumanth
  • 91
  • 1
  • 10
0

Get a marker reference when call addMarker. After when the camera moves, moves the marker to the target position returned by the camera.

private Marker marker;

public void onMapReady(final GoogleMap googleMap) {
        LatLng sydney = new LatLng(-34, 151);
        MarkerOptions markerOptions = new MarkerOptions().position(sydney).title("Marker in Sydney");
        marker = googleMap.addMarker(markerOptions);
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
        googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
            @Override
            public void onCameraMove() {
                final LatLng target = googleMap.getCameraPosition().target;
                marker.setPosition(target);
            }
        });
}
mabg
  • 1,894
  • 21
  • 28