How to move the Android Google Maps API Compass Position
Asked Answered
S

10

26

Does anyone know if you can change the compass position within the map?

All I can find is how to enable or disable it. But I need to move it down a bit so my overlay is not obstructing it.

enter image description here

Skerrick answered 23/2, 2013 at 16:53 Comment(0)
T
20

Use GoogleMap.setPadding() method:

https://developers.google.com/maps/documentation/android/map#map_padding

Tideway answered 3/10, 2013 at 8:35 Comment(1)
not a good solution, on zoom to your location you r location will be in the bottom as wellRattly
B
14
@Override
public void onMapReady(GoogleMap map) {

    try {
        final ViewGroup parent = (ViewGroup) mMapView.findViewWithTag("GoogleMapMyLocationButton").getParent();
        parent.post(new Runnable() {
            @Override
            public void run() {
                try {
                    Resources r = getResources();
                    //convert our dp margin into pixels
                    int marginPixels = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());
                    // Get the map compass view
                    View mapCompass = parent.getChildAt(4);

                    // create layoutParams, giving it our wanted width and height(important, by default the width is "match parent")
                    RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(mapCompass.getHeight(),mapCompass.getHeight());
                    // position on top right
                    rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
                    rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                    rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                    rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0);
                    //give compass margin
                    rlp.setMargins(marginPixels, marginPixels, marginPixels, marginPixels);
                    mapCompass.setLayoutParams(rlp);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
    } catch (Exception ex) {
        ex.printStackTrace();
    }

}
Basalt answered 8/7, 2016 at 12:35 Comment(0)
B
4

I know it's been a long time that the question was asked , but I feld on this issue a few days ago I fixed the problem like this :

try {
                assert mapFragment.getView() != null;
                final ViewGroup parent = (ViewGroup) mapFragment.getView().findViewWithTag("GoogleMapMyLocationButton").getParent();
                parent.post(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            for (int i = 0, n = parent.getChildCount(); i < n; i++) {
                                View view = parent.getChildAt(i);
                                RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) view.getLayoutParams();
                                // position on right bottom
                                rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
                                rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP,0);
                                rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                                rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                                rlp.rightMargin = rlp.leftMargin;
                                rlp.bottomMargin = 25;
                                view.requestLayout();
                            }
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                });
            } catch (Exception ex) {
                ex.printStackTrace();
            }

in this exemple i put the compass in the corner right. You need to be sure that your mapFragment is created when you do this, i suggest you run your code in the method "onMapReady" of your MapFragment.

Bezique answered 6/8, 2015 at 13:8 Comment(2)
this is placed on bottm left rof some reason!Monoacid
it still works now in 2023.Grau
C
3

As I know you can't change compass position but you can disable it and build yours private one.

See example here

Capillaceous answered 23/2, 2013 at 16:59 Comment(3)
+1 Interesting. Let's see if anyone comes up with a workaround, if not the credit is all yours.Skerrick
But this is using MapView. Any idea with MapFragment?Postgraduate
include fragment into activity layout and it will work same as MapView.Rodriquez
I
2

Better use following snippet:

mapView.findViewWithTag<View>("GoogleMapCompass")?.let { compass ->
    compass.post {
        val topMargin = compass.marginTop
        val rlp = RelativeLayout.LayoutParams(compass.height, compass.height)
        rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0)
        rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP)
        rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
        rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0)

        val endMargin = (4 * Resources.getSystem().displayMetrics.density).toInt()
        rlp.setMargins(0, topMargin, endMargin, 0)
        compass.layoutParams = rlp
    }
}

This way you don't have to use "GoogleMapMyLocationButton" and go over the parent. Iterating to the parent doesn't bring any benefit and could break more easy in the future, when google provides an update of the mapView. Within that code snipped you directly access the compass, that's the element you need here.

Iciness answered 13/12, 2021 at 15:29 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Fixate
S
1

Padding-based solutions work for small offsets, but as far as I know there's no API exposed that allows us to robustly change the horizontal "gravity" of the compass from left to right like the stock Google Maps app does:

enter image description here

Note that if you applied a large amount of left padding to move the compass to the right in your own app, the Google logo in the bottom left would also be shifted over to the right.

Sufficiency answered 17/11, 2016 at 19:58 Comment(0)
D
1

On 2.0 map api.

        // change compass position 
    if (mapView != null &&
            mapView.findViewById(Integer.parseInt("1")) != null) {
        // Get the view
        View locationCompass = ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("5"));
        // and next place it, on bottom right (as Google Maps app)
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
                locationCompass.getLayoutParams();
        // position on right bottom
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
        layoutParams.setMargins(0, 160,30, 0); // 160 la truc y , 30 la  truc x
    }
Datcha answered 11/2, 2017 at 15:0 Comment(0)
S
1

Based on the answer of @Vignon (https://mcmap.net/q/517869/-how-to-move-the-android-google-maps-api-compass-position), here is a Kotlin code snippet to position the compass icon to the top right of the screen. You can also add custom margins (in this example the compass image has a marginTop of 50dp).

mapFragment?.view?.let { mapView ->
  mapView.findViewWithTag<View>("GoogleMapMyLocationButton").parent?.let { parent ->
    val vg: ViewGroup = parent as ViewGroup
    vg.post {
      val mapCompass: View = parent.getChildAt(4)
      val rlp = RelativeLayout.LayoutParams(mapCompass.height, mapCompass.height)
      rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0)
      rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP)
      rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
      rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0)

      val topMargin = (50 * Resources.getSystem().displayMetrics.density).toInt()
      rlp.setMargins(0, topMargin, 0, 0)    
      mapCompass.layoutParams = rlp
    }
  }
 }
Storey answered 2/4, 2020 at 9:47 Comment(0)
R
0

There is my solution.

First of all, I need this Kotlin extension to get all subview for any view

fun View.getAllChildren(): List<View> {
    val result = ArrayList<View>()
    if (this !is ViewGroup) {
        result.add(this)
    } else {
        for (index in 0 until this.childCount) {
            val child = this.getChildAt(index)
            result.addAll(child.getAllChildren())
        }
    }
    return result
}

After that, I just retrieve the compass by looking for it with his content description (Use Layout Inspector to retrieve it just in cas if content description change in the future).

When you have your view, change his position like this:

    binding.mapView
            .getAllChildren()
            .firstOrNull { it.contentDescription == "Compass" }
            ?.let { it.y = it.y + 400 }
React answered 13/1, 2021 at 15:15 Comment(0)
D
0

Following @Vignon herre's a suggestion for position the compass in lower left corner (in kotlin):

            mapFragment.view?.let { mapView->
                mapView.findViewWithTag<View>("GoogleMapMyLocationButton").parent?.let { parent->
                    val vg: ViewGroup = parent as ViewGroup
                    vg.post {
                        val mapCompass :View = parent.getChildAt(4)
                        val rlp = RelativeLayout.LayoutParams(mapCompass.height, mapCompass.height)
                        rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
                        rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP,0)
                        rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,0)
                        rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)

                        val bottomMargin = (40 * Resources.getSystem().displayMetrics.density).toInt()
                        val leftMargin = (5 * Resources.getSystem().displayMetrics.density).toInt()
                        rlp.setMargins(leftMargin,0,0,bottomMargin)
                        mapCompass.layoutParams = rlp
                    }
                }
            }
Dipole answered 13/4, 2021 at 18:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.