28

How can i customize the position of the builtin zoom controls in a GoogleMap V2 ?

There are a lot of questions related to this topic for the Version 1 of Google Maps library.

Placing Zoom Controls in a MapView

How to reposition built-in zoom controls in MapView?

How to layout zoom Control with setBuiltInZoomControls(true)?

However, i wasn't able to find any questions in relation to the V2 of the library.

In the V2, there's no method

(LinearLayout) mapView.getZoomControls();

all the previously mentioned questions becomes obsolete.

Thanks in advance

Community
  • 1
  • 1
Robert Estivill
  • 12,369
  • 8
  • 43
  • 64

4 Answers4

39

Depending on what you're trying to do, you might find GoogleMap.setPadding() useful (added in September 2013).

map.setPadding(leftPadding, topPadding, rightPadding, bottomPadding);

From the API docs:

This method allows you to define a visible region on the map, to signal to the map that portions of the map around the edges may be obscured, by setting padding on each of the four edges of the map. Map functions will be adapted to the padding. For example, the zoom controls, compass, copyright notices and Google logo will be moved to fit inside the defined region, camera movements will be relative to the center of the visible region, etc.

Also see the description of how padding works in GoogleMap.

Mark Doliner
  • 1,543
  • 15
  • 17
26

Yes, you can change position of ZoomControl and MyLocation button with small hack. In my sample I have SupportMapFragment, which is inflated from xml layout.

View ids for ZoomControl and MyLocation button:

ZoomControl id = 0x1
MyLocation button id = 0x2

Code to update ZoomControl position:

// Find map fragment
SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);

// Find ZoomControl view
View zoomControls = mapFragment.getView().findViewById(0x1);

if (zoomControls != null && zoomControls.getLayoutParams() instanceof RelativeLayout.LayoutParams) {
    // ZoomControl is inside of RelativeLayout
    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) zoomControls.getLayoutParams();

    // Align it to - parent top|left
    params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);

    // Update margins, set to 10dp
    final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10,
            getResources().getDisplayMetrics());
    params.setMargins(margin, margin, margin, margin);
}
vovkab
  • 1,292
  • 11
  • 17
  • How can you ensure mapFragment.getView().findViewById(0x1); will always return the RelativeLayout with the zoom controls in it? As far as i know, that's usually a random integer generated by the android tools when they generate the R class. Am i missing something? – Robert Estivill Feb 19 '13 at 12:13
  • 2
    Because they are explicitly do ZoomControl.setId(1) and MyLocationButton.setId(2). So it should work fine, until they change ids. And there is also a third control with 0x3, but I'm not sure what it is for. – vovkab Feb 19 '13 at 19:27
  • 1
    Thank you for your answer. Though, i will keep the accepted answer because this is a hack, and not backed up by documentation. – Robert Estivill Feb 20 '13 at 15:56
  • I'm using the construction `GoogleMap gMap2 = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapViewAPI2)).getMap();` and couldn't determine how to access the mapFragment you referenced. Can you advise? Thanks! – PeteH Apr 10 '13 at 05:44
  • Your map fragment is : `SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapViewAPI2);` If you need GoogleMap object you can then do: `GoogleMap gMap2 = mapFragment.getMap();` – vovkab Apr 13 '13 at 04:41
  • Thanks for the answer and for guidance on the map fragment. I just +1'd you. – PeteH Apr 15 '13 at 09:07
  • 3
    This is insanely fragile. These values can change with any Maps V2 release. Please simply hide the built-in zoom controls and add your own. – CommonsWare Apr 30 '13 at 11:59
  • 1
    Hi vovkab, is it possible to reposition (i.e 50 dip below) the Compass button of map v2? If possible please give a response. – Helal Khan May 05 '13 at 10:53
  • Even though it's a hack, it's an amazing one nonetheless. Kudos! BTW what would be the ID for the Compass? – Sheharyar Aug 08 '13 at 06:50
  • @vovkab adding if you wanna align at center vertical try it works for me `( ( LinearLayout ) zoomControls ).setGravity( Gravity.CENTER_VERTICAL );` – Idemax Oct 10 '13 at 19:16
  • Although fragile, amazing solution. One problem: it works just great for zooming controls, but it does not work for my location button. It stretches and covers all the fragment (like it were aligned to the 4 corners). I've even tried to create new LayourParams but it keeps doing the same :( – luixal Oct 13 '13 at 13:45
  • In fact, using `params.removeRule(RelativeLayout.ALIGN_PARENT_TOP)` and `params.removeRule(RelativeLayout.ALIGN_PARENT_RIGHT);` and adding aligns to bottom and left does the trick, but `removeRule`is only available from SDK 17, which sucks. – luixal Oct 13 '13 at 13:50
  • Just to add Toolbar Id = 0x3 – BostonGeorge Oct 30 '15 at 02:35
  • MapView currently do not support Left and Right like ALIGN_PARENT_LEFT and in setMargin. Instead use Start and End like ALIGN_PARENT_START and params.setMarginStart(margin) – nitinkumarp May 25 '17 at 05:36
1

I use MapFragment not SupportMapFragment:

import android.util.TypedValue;

in onCreate

    // Find map fragment

    MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.mapview);

    int ZoomControl_id = 0x1;
    int MyLocation_button_id = 0x2;

    // Find ZoomControl view
    View zoomControls = mapFragment.getView().findViewById(ZoomControl_id);

    if (zoomControls != null && zoomControls.getLayoutParams() instanceof RelativeLayout.LayoutParams) {
        // ZoomControl is inside of RelativeLayout
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) zoomControls.getLayoutParams();

        // Align it to - parent top|left
        params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);

        // Update margins, set to 10dp
        final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10,
                getResources().getDisplayMetrics());
        params.setMargins(margin, margin, margin, margin);
    }
Ingo
  • 5,239
  • 1
  • 30
  • 24
  • Thanks! this is exactly what I needed. Other solutions on SO are either deprecated or didn't work for me. I just had to use `zoomControls.setPadding(20,0,0,20);` instead because `margin` didn't work, not sure why. – ybloodz Jul 30 '20 at 10:55
0

Just for the record:

Navigation-controls are 0x4

So in total:

@LayoutRes final int ZOOM_CONTROL_ID = 0x1;
@LayoutRes final int MY_LOCATION_CONTROL_ID = 0x2;
@LayoutRes final int NAVIGATION_CONTROL_ID = 0x4;
Langusten Gustel
  • 10,917
  • 9
  • 46
  • 59