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.
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.
Use GoogleMap.setPadding() method:
https://developers.google.com/maps/documentation/android/map#map_padding
@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();
}
}
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.
As I know you can't change compass position but you can disable it and build yours private one.
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.
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:
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.
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
}
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
}
}
}
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 }
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
}
}
}
© 2022 - 2024 — McMap. All rights reserved.