Suppose that we have a centered marker on the map, when we move the map with our fingers we can see that marker would no longer displayed when you got out of bounds of the area. So how can we make a marker that would remain always on the center of the map although we move the map anywhere? There is an app named UBER and they provide this feature, you don't drag and drop the marker you just move the map and the marker remained it's position.
Here is a screenshot:
As you can see green marker is on the center of screen when we move the map it remained its place but shows the new position when the user stop moving the map. How can we do like this?
I have a code that shows the address when you drag&drop the marker, how about displaying the address again but this time not by dragging, moving the map? Hope you can understand any ideas would be great.
public class MainActivity extends AbstractMapActivity implements OnNavigationListener, OnInfoWindowClickListener, OnMarkerDragListener { private static final String STATE_NAV="nav"; private static final int[] MAP_TYPE_NAMES= { R.string.normal, R.string.hybrid, R.string.satellite, R.string.terrain }; private static final int[] MAP_TYPES= { GoogleMap.MAP_TYPE_NORMAL, GoogleMap.MAP_TYPE_HYBRID, GoogleMap.MAP_TYPE_SATELLITE, GoogleMap.MAP_TYPE_TERRAIN }; private GoogleMap map=null; String filterAddress = ""; Marker marker; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (readyToGo()) { setContentView(R.layout.activity_main); SupportMapFragment mapFrag= (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map); mapFrag.setRetainInstance(true); initListNav(); map=mapFrag.getMap(); if (savedInstanceState == null) { CameraUpdate center= CameraUpdateFactory.newLatLng(new LatLng( 41.003739, 28.999572)); CameraUpdate zoom=CameraUpdateFactory.zoomTo(10); map.moveCamera(center); map.animateCamera(zoom); addMarker(map, 41.003739, 28.999572, R.string.un, R.string.united_nations); map.setInfoWindowAdapter(new PopupAdapter(getLayoutInflater())); map.setOnInfoWindowClickListener(this); map.setOnMarkerDragListener(this); } } } @Override public boolean onNavigationItemSelected(int itemPosition, long itemId) { map.setMapType(MAP_TYPES[itemPosition]); return(true); } @Override public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); savedInstanceState.putInt(STATE_NAV, getSupportActionBar().getSelectedNavigationIndex()); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); getSupportActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_NAV)); } @Override public void onInfoWindowClick(Marker marker) { Toast.makeText(this, marker.getTitle(), Toast.LENGTH_LONG).show(); } @Override public void onMarkerDragStart(Marker marker) { LatLng position=marker.getPosition(); Log.d(getClass().getSimpleName(), String.format("Drag from %f:%f", position.latitude, position.longitude)); } @Override public void onMarkerDrag(Marker marker) { LatLng position=marker.getPosition(); Log.d(getClass().getSimpleName(), String.format("Dragging to %f:%f", position.latitude, position.longitude)); } @Override public void onMarkerDragEnd(Marker marker) { LatLng position=marker.getPosition(); String filterAddress = ""; Geocoder geoCoder = new Geocoder( getBaseContext(), Locale.getDefault()); try { List<Address> addresses = geoCoder.getFromLocation( position.latitude, position.longitude, 1); if (addresses.size() > 0) { for (int index = 0; index < addresses.get(0).getMaxAddressLineIndex(); index++) filterAddress += addresses.get(0).getAddressLine(index) + " "; } }catch (IOException ex) { ex.printStackTrace(); }catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } Log.d(getClass().getSimpleName(), String.format("Dragging to %f:%f", position.latitude, position.longitude)); TextView myTextView = (TextView) findViewById(R.id.test); myTextView.setText("Address is: " + filterAddress); } private void initListNav() { ArrayList<String> items=new ArrayList<String>(); ArrayAdapter<String> nav=null; ActionBar bar=getSupportActionBar(); for (int type : MAP_TYPE_NAMES) { items.add(getString(type)); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { nav= new ArrayAdapter<String>( bar.getThemedContext(), android.R.layout.simple_spinner_item, items); } else { nav= new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, items); } nav.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); bar.setListNavigationCallbacks(nav, this); } private void addMarker(GoogleMap map, double lat, double lon, int title, int snippet) { map.addMarker(new MarkerOptions().position(new LatLng(lat, lon)) .icon(BitmapDescriptorFactory.fromResource(R.drawable.pin)) .draggable(true)); } }
Here is the xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/img_header" > <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.SupportMapFragment" /> <TextView android:id="@+id/test" android:layout_width="match_parent" android:layout_height="90dp" android:layout_alignParentRight="true" android:text="Address : " android:textColor="#FF0000" android:textSize="22sp" /> </RelativeLayout>
Setting a marker's draggable property to true allows the user to change the position of the marker. Use a long press to activate the ability to move the marker.
Panning and Zooming with Google Maps To move the map click and hold the left mouse button and drag the map to a new place. You can also move the map North, South, East or West using the pan arrows. These can be found on the top left hand corner of the map.
You can add a simple marker to the map at a desired location by instantiating the marker class and specifying the position to be marked using latlng, as shown below.
The transition() and moveMarker() are used to move marker smoothly on click on the Google map.
On clicking on the Google Map, the marker moves smoothly and the marker position is changed. Google Maps JavaScript API is used to create the map, so load this API first. You need to specify an API key in API URL for using the Google Maps JavaScript API.
This example script displays a map with a marker using Google Maps JavaScript API. On clicking on the Google Map, the marker moves smoothly and the marker position is changed. Google Maps JavaScript API is used to create the map, so load this API first. You need to specify an API key in API URL for using the Google Maps JavaScript API.
The initialize() function creates a Google Map with a marker. The transition() and moveMarker() are used to move marker smoothly on click on the Google map.
If you are using Fragment to display your google map, put the ImageView inside the Fragment to overlay your customized marker such that your marker remains fixed when you are moving your map. Follow the code for xml file:
I used a RelativeLayout as parent of fragment with map and center in it an ImageView (which will do as the centered map marker just like in uber or easy taxi apps):
<!-- Map and ImageView in center for simulating the map marker --> <RelativeLayout android:id="@+id/confirm_address_map_wrapper" android:layout_width="match_parent" android:layout_height="220dp"> <fragment android:id="@+id/confirm_address_map_fragment" android:name="com.google.android.gms.maps.MapFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" /> <!-- Image View that acts as map marker notice centerInParent--> <View android:id="@+id/view" android:layout_width="1dp" android:layout_height="1dp" android:layout_centerInParent="true"/> <ImageView android:id="@+id/confirm_address_map_custom_marker" android:layout_width="@dimen/ICON_DEFAULT_SIZE" android:layout_height="@dimen/ICON_DEFAULT_SIZE" android:layout_above="@+id/view" android:layout_centerHorizontal="true" android:src="@mipmap/my_map_marker"/> </RelativeLayout>
onMapReady() method at my activity I use googleMap instance method setOnCameraChangeListener()
that lets me listen when the map is used and get latitude and longitude based on the center of camera position:
@Override public void onMapReady(GoogleMap googleMap) { googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { @Override public void onCameraChange(CameraPosition cameraPosition) { Log.i("centerLat",cameraPosition.target.latitude); Log.i("centerLong",cameraPosition.target.longitude); } }); }
UPDATE:OnCameraChangeListener
is deprecated . Please use OnCameraIdleListener
:
[Source: https://stackoverflow.com/a/38732283/421467]
I was not able to get the Uber app effect, however I was able to do something similar, perhaps it will do just fine for your solution making use of the GoogleMap.OnCameraChangeListener.
Activity:
public class MyActivity extends Activity implements OnCameraChangeListener { ... @Override public void onCameraChange(CameraPosition position) { mMap.clear(); mMap.addMarker( new MarkerOptions() .position( position.target ) .title( position.toString() ) ); } ... }
The problem is, the marker is not drawn while the camera is being moved. However, it seems as though you have already created an overlay of a marker. So with an overlay it should work like the Uber application.
I hope this helps, even the question is a few months old, perhaps it will benefit future developers.
Kind regards Miki
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With