Change position of Google Maps API's "My location" button
Solution 1
Just use GoogleMap.setPadding(left, top, right, bottom), which allows you to indicate parts of the map that may be obscured by other views. Setting padding re-positions the standard map controls, and camera updates will use the padded region.
https://developers.google.com/maps/documentation/android/map#map_padding
Solution 2
You can get the "My Location" button and move it, like :
public class MapFragment extends SupportMapFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View mapView = super.onCreateView(inflater, container, savedInstanceState);
// Get the button view
View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);
// and next place it, for exemple, on bottom right (as Google Maps app)
RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
// position on right bottom
rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
rlp.setMargins(0, 0, 30, 30);
}
}
Solution 3
This may not be the best solution, but you could place your own button over the map and handle it yourself. It would take the following:-
1) Put the map in a frameLayout and add your button on top. E.g.
<FrameLayout
android:id="@+id/mapFrame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/mapFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="com.google.android.gms.maps.MapFragment"
map:mapType="normal"
map:uiCompass="true" />
<ImageButton
android:id="@+id/myMapLocationButton"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="bottom|right"
android:background="@drawable/myMapLocationDrawable"
android:contentDescription="My Location" />
</FrameLayout>
2) Edit the maps UI settings so the button doesn't appear when you call setMyLocationEnabled(true). You can do this via map.getUiSettings(). setMyLocationButtonEnabled(false);
3) Handle the click of your new button to emulate what the supplied button does. E.g. call mMap.setMyLocationEnabled(...); and pan the map to the current location.
Hope that helps, or hope someone comes a long with a simpler solution for you ;-)
Solution 4
It's already been explained above.Just a small addition to fabLouis's answer. You may also get your map view from the SupportMapFragment.
/**
* Move the button
*/
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().
findFragmentById(R.id.map);
View mapView = mapFragment.getView();
if (mapView != null &&
mapView.findViewById(1) != null) {
// Get the button view
View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);
// and next place it, on bottom right (as Google Maps app)
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
locationButton.getLayoutParams();
// position on right bottom
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
layoutParams.setMargins(0, 0, 30, 30);
}
Solution 5
I don't fancy seeing these magic view IDs others are using, I suggest using tags to find MapView
s children.
Here is my solution for placing the My Location button above the Zoom controls.
// Get map views
View location_button =_mapView.findViewWithTag("GoogleMapMyLocationButton");
View zoom_in_button = _mapView.findViewWithTag("GoogleMapZoomInButton");
View zoom_layout = (View) zoom_in_button.getParent();
// adjust location button layout params above the zoom layout
RelativeLayout.LayoutParams location_layout = (RelativeLayout.LayoutParams) location_button.getLayoutParams();
location_layout.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
location_layout.addRule(RelativeLayout.ABOVE, zoom_layout.getId());
Related videos on Youtube
Jakob
Updated on October 20, 2020Comments
-
Jakob over 3 years
I am using the Google Maps Android API v2, and I need a way to chance the position of the "My Location" button.
I get the "My Location" button like this:
GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext()); final GoogleMap map = ((SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map)).getMap(); // This gets the button map.setMyLocationEnabled(true);
-
CommonsWare over 11 yearsAFAIK, you don't. You adjust your layout such that the ad does not overlap the map.
-
IgorGanapolsky over 10 yearsHave you looked at the setPadding() method of GoogleMap? See: developers.google.com/maps/documentation/android/…
-
-
Ryan over 11 yearsBTW for what it's worth I agree with CommonsWare, don't cover the map with an advert would be best!
-
clauziere about 11 yearsCould you share your solution please.
-
Nayanesh Gupte over 10 yearsit's giving me java.lang.ClassCastException: maps.af.q cannot be cast to android.view.ViewGroup
-
Swan about 10 yearsHi @fabLouis, First of all, I wanted to thank you. Your code did move the LocationButton. I am just curious that how you figured out that button's Id? Can you explain more about this
mapView.findViewById(1).getParent()).findViewById(2);
. Thanks again, SH -
reidisaki over 9 yearsyeah how did you know findViewById(1) and findViewById(2)
-
reidisaki over 9 yearshow did you know that ((View) getView().findViewById(1).getParent()); would get the location view?
-
fabLouis over 9 yearsvia the Android Studio debugger
-
Roman over 9 yearsThere are a lot of great stuff in Android Studio debugger ;)
-
inmyth about 9 yearsif you do this, Android Studio will say " expected resource of type id"
-
Harsha about 9 years@inmyth Even i got the same error, But i Parsed 1 and 2 using Integer class. findViewById(Integer.parseInt("1")). If you had found better solution let me know.
-
user2968401 about 9 yearshmm how does
RelativeLayout.ALIGN_PARENT_TOP
andRelativeLayout.ALIGN_PARENT_BOTTOM
equal bottom right? -
user2968401 about 9 yearsnvm i get it.
RelativeLayout.ALIGN_PARENT_TOP
isfalse
which essentially negates the property. -
salih almost 9 years@fabLouis I've implemented your code block into the my project. Everything looks fine but my location button didn't work. Even I added setMyLocationenabled(true). How can I solve this issue ? Can you give me any idea ? Thanks
-
zookastos almost 9 yearsThis line - ((View) mapView.findViewById(1).getParent()).findViewById(2); is giving me an error - "Expected resource of type ID" on 1 and 2 integer.
-
zookastos almost 9 yearsThis line - ((View) mapView.findViewById(1).getParent()).findViewById(2); is giving me an error - "Expected resource of type ID" on 1 and 2 integer.
-
Silambarasan Poonguti over 8 yearsTry this - View btnMyLocation = ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
-
Mehmet Katircioglu over 8 yearsHi @fabLouis, is it possible to change the location of the directions button which appears when you click on a marker. I have a floating action button in my activity that hovers over the map and it overlays the directions button of the MapAPI
-
John over 8 yearsGetting this runtime error . Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewParent android.view.View.getParent()' on a null object reference
-
Richard Le Mesurier over 8 years@Nalin There is an option if you Alt-Enter on the error to disable the check (e.g. for the method).
-
firetrap over 8 yearsI've tried to align it to the bottom left but instead it goes to the same position the bottom right. layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,0); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
-
pablobaldez over 8 yearsThis is the best answer. findById(1) is a terrible solution
-
josefdlange about 8 yearsThe absolute clearest and best practice answer. Love it.
-
riper almost 8 yearsWorks well for putting the mylocation button in lower right hand corner, but as you say it messes up camera updates. How to solve that? As of now my camera always sees the bottom of the screen as the center. Do you add half the height of the screen to camera when calculating stuff?
-
Bertoncelj1 almost 8 years@firetrap try this:
rlp.addRule(RelativeLayout.ALIGN_PARENT_END, 0); rlp.addRule(RelativeLayout.ALIGN_END, 0); rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
to move it to the left -
deathangel908 over 7 yearsWorks on
9.4.0
, but not in10.0.1
.mapView.findViewById(1)
returns null -
Zohab Ali over 7 yearsThis line - ((View) mapView.findViewById(1).getParent()).findViewById(2); was giving me an error - "Expected resource of type ID" on 1 and 2 integer then I resolved it like this ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
-
Zohab Ali over 7 yearsThis line - ((View) mapView.findViewById(1).getParent()).findViewById(2); was giving me an error - "Expected resource of type ID" on 1 and 2 integer then I resolved it like this ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
-
ayvazj about 7 yearsI prefer the mapView.findViewWithTag("GoogleMapMyLocationButton"); solution below.
-
zyamys about 7 yearsNote that
setPadding
has lots of other side-effects that may be undesired. Most importantly, it changes the screen position of the camera target. -
zyamys about 7 yearsNote that if you are moving the my location button, you probably also want to move the compass view that's visible when the user rotates the map.
-
zyamys about 7 yearsFor anyone wondering how to do the same for the compass, the tag is
GoogleMapCompass
. -
Sharath Weaver over 6 yearsThanks worked for me. I was trying with only ALIGN_PARENT_BOTTOM but not worked for me. how this is working ?
-
Randy over 6 yearsHey Cord, I don't know if you remember how to do this, but do you remember where you found the list of mapview tags? I'm looking to move some other stuff around and I really dislike the other patterns people are using.
-
ElegyD over 6 years@Randy Iterate through the subviews of the MapView (FrameLayout) and log the tag's to get them. See here (Written in Kotlin)
-
Randy over 6 years@ElegyD Thank you!!
-
Md Shihab Uddin over 6 yearsyou need to cast (view) like mapView = (View)mapFragment.getView();
-
aLL about 5 yearson
rlp.setMargins(0, 0, 30, 30);
only the 4th param, 30 for bottom margin applies. Try changing the 3rd param to 100, it doesn't apply. -
aLL about 5 yearsafter trying all
setLayoutParams(int,int,int,int)
, I conclude that onlyTOP
andBOTTOM
margins can be set. -
Nacho Zullo over 3 yearsThank u very much