Change position of Google Maps API's "My location" button

78,612

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 MapViews 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());
Share:
78,612

Related videos on Youtube

Jakob
Author by

Jakob

Updated on October 20, 2020

Comments

  • Jakob
    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);
    
  • Ryan
    Ryan over 11 years
    BTW for what it's worth I agree with CommonsWare, don't cover the map with an advert would be best!
  • clauziere
    clauziere about 11 years
    Could you share your solution please.
  • Nayanesh Gupte
    Nayanesh Gupte over 10 years
    it's giving me java.lang.ClassCastException: maps.af.q cannot be cast to android.view.ViewGroup
  • Swan
    Swan about 10 years
    Hi @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
    reidisaki over 9 years
    yeah how did you know findViewById(1) and findViewById(2)
  • reidisaki
    reidisaki over 9 years
    how did you know that ((View) getView().findViewById(1).getParent()); would get the location view?
  • fabLouis
    fabLouis over 9 years
    via the Android Studio debugger
  • Roman
    Roman over 9 years
    There are a lot of great stuff in Android Studio debugger ;)
  • inmyth
    inmyth about 9 years
    if you do this, Android Studio will say " expected resource of type id"
  • Harsha
    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
    user2968401 about 9 years
    hmm how does RelativeLayout.ALIGN_PARENT_TOP and RelativeLayout.ALIGN_PARENT_BOTTOM equal bottom right?
  • user2968401
    user2968401 about 9 years
    nvm i get it. RelativeLayout.ALIGN_PARENT_TOP is false which essentially negates the property.
  • salih
    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
    zookastos almost 9 years
    This line - ((View) mapView.findViewById(1).getParent()).findViewById(2); is giving me an error - "Expected resource of type ID" on 1 and 2 integer.
  • zookastos
    zookastos almost 9 years
    This 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
    Silambarasan Poonguti over 8 years
    Try this - View btnMyLocation = ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).fin‌​dViewById(Integer.pa‌​rseInt("2"));
  • Mehmet Katircioglu
    Mehmet Katircioglu over 8 years
    Hi @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
    John over 8 years
    Getting 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
    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
    firetrap over 8 years
    I'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
    pablobaldez over 8 years
    This is the best answer. findById(1) is a terrible solution
  • josefdlange
    josefdlange about 8 years
    The absolute clearest and best practice answer. Love it.
  • riper
    riper almost 8 years
    Works 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
    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
    deathangel908 over 7 years
    Works on 9.4.0, but not in 10.0.1. mapView.findViewById(1) returns null
  • Zohab Ali
    Zohab Ali over 7 years
    This 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()).fin‌​dViewById(Integer.pa‌​rseInt("2"));
  • Zohab Ali
    Zohab Ali over 7 years
    This 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()).fin‌​dViewById(Integer.pa‌​rseInt("2"));
  • ayvazj
    ayvazj about 7 years
    I prefer the mapView.findViewWithTag("GoogleMapMyLocationButton"); solution below.
  • zyamys
    zyamys about 7 years
    Note that setPadding has lots of other side-effects that may be undesired. Most importantly, it changes the screen position of the camera target.
  • zyamys
    zyamys about 7 years
    Note 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
    zyamys about 7 years
    For anyone wondering how to do the same for the compass, the tag is GoogleMapCompass.
  • Sharath Weaver
    Sharath Weaver over 6 years
    Thanks worked for me. I was trying with only ALIGN_PARENT_BOTTOM but not worked for me. how this is working ?
  • Randy
    Randy over 6 years
    Hey 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
    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
    Randy over 6 years
    @ElegyD Thank you!!
  • Md Shihab Uddin
    Md Shihab Uddin over 6 years
    you need to cast (view) like mapView = (View)mapFragment.getView();
  • aLL
    aLL about 5 years
    on 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
    aLL about 5 years
    after trying all setLayoutParams(int,int,int,int), I conclude that only TOP and BOTTOM margins can be set.
  • Nacho Zullo
    Nacho Zullo over 3 years
    Thank u very much